[英]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.