Подтвердить что ты не робот

"новый" внутри бетонного типа вызывается только один раз

У меня простой запрос 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 во всех экземплярах.

Когда я заменяю запрос LINQ на foreach, он работает как ожидалось:

  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, обеспечивает хорошее обходное решение. Проверьте этот вариант для подробного описания: "new" внутри бетонного типа вызывается только один раз

4b9b3361

Ответ 1

Пробовали ли вы использовать объект SomeLinq2SqlEntity с linq для объектов?

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

Ответ 2

Вероятно, это связано со странной реализацией вашего провайдера IQueryable. Ответ Aducci извлекает данные из базы данных с вызовом AsEnumerable() и выполняет запрос на этом наборе, который отличается от выполнения через IQueryable.

Например, IQueryable создает ExpressionTree, который позже анализирует в соответствии с конкретным провайдером (т.е. выполняет общий код один раз для оптимизации), тогда как IEnumerable принимает Func и выполняет его так, как вы ожидали.

Вы можете прочитать здесь:

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