本文介绍了C#匿名类型的foreach循环,更好的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个匿名类型的简单的 foreach 循环,我想知道是否有办法使它更有效率。

如果它循环了155项,大约需要20秒才能完成。我省略了它在 boAsset 对象上设置的其他一些属性,但没有什么特别的 - 只是字符串 / 整数



有什么想法吗? 列表与LT; BoAsset> assetList = new List< BoAsset>();
foreach(var结果中的资产)
{
BoAsset boAsset = new BoAsset();
boAsset.Description = asset.Description;
boAsset.DetailedDescription = asset.DetailedDescription;
boAsset.AssetCustomerID = asset.AssetCustomerID;
boAsset.AssetId = asset.AssetId;
boAsset.Keywords = asset.Keywords;
boAsset.Notes = asset.Notes;
boAsset.Photographer = asset.Photographer;
boAsset.PhotographerEmail = asset.PhotographerEmail;
boAsset.Notes = asset.Notes;
boAsset.Author = asset.Author;
boAsset.FileName = asset.FileName;
boAsset.FileExtension = asset.FileExtension;
boAsset.AssetCreateDate = asset.AssetCreateDate;
boAsset.AssetExpireDate = asset.AssetExpireDate;

assetList.Add(boAsset);



var query =(从一个in context.Assets
加入subAf1到context.AssetFiles新的{aid = a.AssetID,ftid = 1}将新的{aid = subAf1.AssetID,ftid = subAf1.AssetTypeID}放入Af1中的Af1
中.Af1.DefaultIfEmpty()
加入subAf2中的context.AssetFiles on {aid = a.AssetID,ftid = 2}将等于new {aid = subAf2.AssetID,ftid = subAf2.AssetTypeID}放入Af2中的Af2
中的Af2.DefaultIfEmpty()
加入subAf3中的context.AssetFiles on {aid = a.AssetID,在新的{aid = a。}中,从Af3.DefaultIfEmpty()
加入subAf4到新的{aid = subAf3.AssetID,ftid = subAf3.AssetTypeID}到Af3
。 AssetID,ftid = 4}将等于new {aid = subAf4.AssetID,ftid = subAf4.AssetTypeID}放入Af4中的Af4
中.Af4.DefaultIfEmpty()
在context.AssetFiles中加入subAf5新的{aid = a.AssetID,ftid = 5}将等于new {aid = subAf5.AssetID,ftid = subAf5.AssetTypeID}放入Af5中的Af5
中的Af5.DefaultIfEmpty()
在上下文中加入subFp。在{fpid = Af1.FilePathID}上的FilePaths等于new {fpid = subFp.FilePathID}从Fp1.DefaultIfEmpty()
中的fp1到Fp1
中//在context中加入fp。Af1.FilePathID上的FilePath等于fp.FilePathID

其中a.AssetCustomerID == custId&& a.AssetID == assetId
选择新{a,Af1,Af2,Af3,Af4,Af5,fp1})。Distinct();
$ b $ var result =从查询中的q
选择新的
{
AssetId = qaAssetID,
AssetCustomerId = qaAssetCustomerID,
StockImage = qaStockImage,
Description = qaDescription,
DetailedDescription = qaDetailedDescription,
Author = qaAuthor,
FileName = q.Af1.FileName,// was 1
FileExtension = q.Af1.FileExtension,//为1
AssetCreateDate = qaAssetCreateDate,
AssetExpireDate = qaAssetExpireDate,
AssetActivateDate = qaAssetActivateDate,

Notes = qa注意,
关键字= qa关键字,
摄影师= qa摄影师,
摄影师电子邮件= qa摄影师电子邮箱
}


解决方案

我认为您的查询太复杂许多连接),尤其是考虑到有一些甚至没有被使用。注意,一些LINQ提供者(比如LINQ to Entities)可能会花费相当多的时间只要简单地处理一个查询树就可以把它转换成SQL,如果查询很复杂。 (我已经有一些查询需要10或15秒,只是为了分析EF)。

如果我怀疑你正在使用的LINQ实现命中一个数据库,然后使用一个SQL分析工具来检查传递给服务器的实际SQL,以及SQL是如何执行的。

另外,请注意,给定你正在使用的字段,你可以通过物化来消除 foreach 直接返回到 BoAsset 对象。





  var result = from查询中的q 
选择新的BoAsset
{
AssetId = qaAssetID,
AssetCustomerId = qaAssetCustomerID,
StockImage = qaStockImage,
描述= qaDescription,
DetailedDescription = qaDetailedDescription,
Author = qaAuthor,
FileName = q.Af1.FileName,// was 1
FileExtension = q.Af1.FileExtension,//为1
AssetCreateDate = qaAssetCreateDate,
AssetExpireDate = qaAssetExpireDate,
AssetActivateDate = qaAssetActivateDate,
不es = q.a.Notes,
Keywords = q.a.Keywords,
Photographer = q.a.Photographer,
PhotographerEmail = q.a.PhotographerEmail
};

列表< BoAsset> assetList = result.ToList();


I have this simple foreach loop of an anonymous type and I'm wondering if there is a way to make it more efficient.

If it loops through 155 items, it takes about 20 seconds to complete. I've omitted some of the other properties it's setting on the boAsset object, but nothing special - just Strings/Integers.

Any thoughts?

List<BoAsset> assetList = new List<BoAsset>();
foreach (var asset in result)
{
     BoAsset boAsset = new BoAsset();
     boAsset.Description = asset.Description;
     boAsset.DetailedDescription = asset.DetailedDescription;
     boAsset.AssetCustomerID = asset.AssetCustomerID;
     boAsset.AssetId = asset.AssetId;
     boAsset.Keywords = asset.Keywords;
     boAsset.Notes = asset.Notes;
     boAsset.Photographer = asset.Photographer;
     boAsset.PhotographerEmail = asset.PhotographerEmail;
     boAsset.Notes = asset.Notes;
     boAsset.Author = asset.Author;
     boAsset.FileName = asset.FileName;
     boAsset.FileExtension = asset.FileExtension;
     boAsset.AssetCreateDate = asset.AssetCreateDate;
     boAsset.AssetExpireDate = asset.AssetExpireDate;

     assetList.Add(boAsset);
}


var query =   (from a in context.Assets
              join subAf1 in context.AssetFiles on new { aid = a.AssetID, ftid = 1 } equals new { aid = subAf1.AssetID, ftid = subAf1.AssetTypeID } into theAf1
              from Af1 in theAf1.DefaultIfEmpty()
              join subAf2 in context.AssetFiles on new { aid = a.AssetID, ftid = 2 } equals new { aid = subAf2.AssetID, ftid = subAf2.AssetTypeID } into theAf2
              from Af2 in theAf2.DefaultIfEmpty()
              join subAf3 in context.AssetFiles on new { aid = a.AssetID, ftid = 3 } equals new { aid = subAf3.AssetID, ftid = subAf3.AssetTypeID } into theAf3
              from Af3 in theAf3.DefaultIfEmpty()
              join subAf4 in context.AssetFiles on new { aid = a.AssetID, ftid = 4 } equals new { aid = subAf4.AssetID, ftid = subAf4.AssetTypeID } into theAf4
              from Af4 in theAf4.DefaultIfEmpty()
              join subAf5 in context.AssetFiles on new { aid = a.AssetID, ftid = 5 } equals new { aid = subAf5.AssetID, ftid = subAf5.AssetTypeID } into theAf5
              from Af5 in theAf5.DefaultIfEmpty()
              join subFp in context.FilePaths on new { fpid = Af1.FilePathID } equals new { fpid = subFp.FilePathID } into theFp1
              from fp1 in theFp1.DefaultIfEmpty()
              //join fp in context.FilePaths on Af1.FilePathID equals fp.FilePathID

              where a.AssetCustomerID == custId && a.AssetID == assetId
              select new { a, Af1, Af2, Af3, Af4, Af5, fp1 }).Distinct();

var result =   from q in query
               select new
               {
                   AssetId = q.a.AssetID,
                   AssetCustomerId = q.a.AssetCustomerID,
                   StockImage = q.a.StockImage,
                   Description = q.a.Description,
                   DetailedDescription = q.a.DetailedDescription,
                   Author = q.a.Author,
                   FileName = q.Af1.FileName, //was 1
                   FileExtension = q.Af1.FileExtension, //was 1
                   AssetCreateDate = q.a.AssetCreateDate,
                   AssetExpireDate = q.a.AssetExpireDate,
                   AssetActivateDate = q.a.AssetActivateDate,

                   Notes = q.a.Notes,
                   Keywords = q.a.Keywords,
                       Photographer = q.a.Photographer,
                       PhotographerEmail = q.a.PhotographerEmail
               }
解决方案

I think that your query is far too complex (too many joins), especially given that there are a few that are not even used.

Note that some LINQ providers (such as LINQ to Entities) can take quite a bit of time in simply processing a query tree to transform it into SQL, if the query is complex. (I have already had some queries take 10 or 15 seconds just for EF to analyze it.)

If, as I suspect, the LINQ implementation that you are using is hitting a database, then use a SQL profiling tool in order to check what actual SQL is being passed to the server, and how performant that SQL is.

Also, note that given the fields you are using, you could actually do away with the foreach loop by materializing results directly into the BoAsset objects.

That is:

var result = from q in query
             select new BoAsset
             {
                 AssetId = q.a.AssetID,
                 AssetCustomerId = q.a.AssetCustomerID,
                 StockImage = q.a.StockImage,
                 Description = q.a.Description,
                 DetailedDescription = q.a.DetailedDescription,
                 Author = q.a.Author,
                 FileName = q.Af1.FileName, //was 1
                 FileExtension = q.Af1.FileExtension, //was 1
                 AssetCreateDate = q.a.AssetCreateDate,
                 AssetExpireDate = q.a.AssetExpireDate,
                 AssetActivateDate = q.a.AssetActivateDate,
                 Notes = q.a.Notes,
                 Keywords = q.a.Keywords,
                 Photographer = q.a.Photographer,
                 PhotographerEmail = q.a.PhotographerEmail
             };

List<BoAsset> assetList = result.ToList();

这篇关于C#匿名类型的foreach循环,更好的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-04 20:02