简体   繁体   English

C#匿名类型foreach循环,更好的方法吗?

[英]C# Anonymous type foreach loop, a better way?

I have this simple foreach loop of an anonymous type and I'm wondering if there is a way to make it more efficient. 我有一个简单的匿名类型的foreach循环,我想知道是否有一种方法可以使它更有效。

If it loops through 155 items, it takes about 20 seconds to complete. 如果它遍历155个项目,则大约需要20秒才能完成。 I've omitted some of the other properties it's setting on the boAsset object, but nothing special - just Strings / Integers . 我已经省略了它在boAsset对象上设置的其他一些属性,但是没有什么特别的-只是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
               }

The time for creating 155 objects and copying the data into them would be something like a millisecond. 创建155个对象并将数据复制到其中的时间大约是毫秒。 There is nothing that you could do to that code to make any significant (or even noticable) improvement. 您无法对该代码做任何重大的(甚至引人注目的)改进。

If you want to save any time, you should look at the query that creates the result. 如果您想节省任何时间,则应查看创建结果的查询。 That's what's taking time. 那就是时间。

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. 请注意,如果查询很复杂,某些LINQ提供程序(例如LINQ to Entities)在处理查询树以将其转换为SQL时可能会花费大量时间。 (I have already had some queries take 10 or 15 seconds just for EF to analyze it.) (我已经有一些查询需要10或15秒才能让EF分析。)

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. 如果我怀疑您正在使用的LINQ实现正在访问数据库,请使用SQL性能分析工具以检查将什么实际SQL传递给服务器以及该SQL的性能如何。

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. 另外,请注意,给定您正在使用的字段,实际上可以通过将结果直接实现到BoAsset对象中来消除foreach循环。

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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM