混凝土型投影内的“新”只被调用一次

时间:2011-08-01 14:23:59

标签: c# linq linq-to-sql

我简单的Linq2Sql查询:

var result = from t in MyContext.MyItems
             select new MyViewModelClass()
             {
                 FirstProperty = t,
                 SecondProperty = new SomeLinq2SqlEntity()
             }      

问题在于new SomeLinq2SqlEntity()似乎只对序列执行一次,因此查询结果中MyViewModelClass的所有实例共享一个对象的链接。

更新:以下是我快速检查的方法:

result[0].SecondProperty.MyField = 10;

使用调试器我可以检查MyField在所有情况下都设置为10

当我用foreach替换LINQ查询时,它按预期工作:

  var result = from t in MyContext.MyItems select t;
  var list = new List<MyViewModelClass>();
  foreach (var item in result)
  {
      list.add(new MyViewModelClass()
             {
                 FirstProperty = item,
                 SecondProperty = new SomeLinq2SqlEntity()
             });       
  }

我没有找到问题的根源,但标记为asnwer的帖子提供了良好的解决方法。请查看此asnwer以获取详细说明:"new" inside concrete type projection is only called once

2 个答案:

答案 0 :(得分:4)

这可能与您的提供商的奇怪IQueryable实施有关。 Aducci的答案通过AsEnumerable()调用从数据库中提取数据,并对该集合执行查询,这与通过IQueryable执行查询不同。

例如IQueryable构建ExpressionTree,稍后根据具体提供程序解析它(即执行共享代码一次以进行优化),而IEnumerable接受Func并执行它期望的。

您可以在这里阅读更多内容:

http://msdn.microsoft.com/en-us/vcsharp/ff963710

答案 1 :(得分:2)

您是否尝试过将SomeLinq2SqlEntity对象与linq一起添加到对象?

var result = (from t in MyContext.MyItems
             select new
             {
                 FirstProperty = t
             })
             .AsEnumerable() 
             .Select(t => new MyViewModelClass()
             {
                 FirstProperty = t.FirstProperty ,
                 SecondProperty = new SomeLinq2SqlEntity();
             });