"новый" внутри бетонного типа вызывается только один раз
У меня простой запрос 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" внутри бетонного типа вызывается только один раз
Ответы
Ответ 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