2012-04-30 3 views
0

У меня есть представление, где один из соединенных столбцов имеет значение NULL, но часто является единственным отличительным элементом между двумя строками. Я вижу, что EF построил первичный ключ из всех элементов, не имеющих значения NULL в представлении. Я заметил, что когда я выхожу из представления, этот столбец с нулевым значением не всегда возвращается корректно, и я читаю, что он связан с тем, как он сопоставляется с ключом, и возвращает ту же строку, если видит ключ уже существует.Каков наилучший способ заставить EF возвращать все строки в виде?

В идеале лучшим решением было бы сделать мой столбец недействительным, но я не могу этого сделать, не вызывая больших проблем.

Другой идеей было использовать ROW_NUMBER() для создания первичного ключа. Я не уверен, что это может вызвать подобные проблемы (если контекст не обновляется между вызовами, будет ли он полностью отключен от него или он достаточно умен, чтобы понять, что запросы разные?) Я также беспокоюсь о производительности, связанной с необходимостью использования ORDER BY для функция и то, как это повлияет на динамическое упорядочение строк.

Каков наилучший способ гарантировать, что все мои строки будут возвращены точно так же, как они появляются через SQL-запрос с наименьшим ударом по производительности?

Спасибо ..

Пример:

view: A int, B int, C int? 

SQL Results: 
1, 2, null 
1, 3, 10 
1, 3, 11 

EF вернет что-то вроде:

1, 2, null 
1, 3, 10 
1, 3, 10 

Мне нужно получить, что 11 тоже.

ответ

3

Это происходит из-за шаблона карты идентификации. По умолчанию EF отслеживает уже загруженные объекты (идентифицированные ключом сущности) - если в результирующем наборе содержится повторяющийся ключ сущности EF, он считает, что это тот же объект, что и тот, который уже загружен, и он не создает новый экземпляр сущности для этих повторяя записи - вместо этого он использует экземпляр, созданный для первой записи с этим ключом. Это необходимо для отслеживания изменений и для возможности сохранения изменений в базе данных.

В вашем случае вы, скорее всего, не хотите сохранять изменения в базу данных, потому что эти записи не дают вам необходимой информации, чтобы иметь возможность сделать это. Поэтому загружайте записи без отслеживания изменений и он должен пропускать шаблон карты идентификации и генерировать новый экземпляр объекта для каждой записи в результирующем наборе:

context.YourEntitySet.MergeOption = MergeOption.NoTracking; 
// Now execute your query 
+0

Спасибо. Это был трюк, который я искал. Я нашел хорошую информацию о http://msmvps.com/blogs/kevinmcneish/archive/2010/02/16/setting-entity-framework-mergeoptions-what-works-what-doesn-t.aspx, чтобы заставить ее работать с моим сценарием. – emragins