Могу ли я заставить EntityFramework 4.1 возвращать запросы, которые возвращают результаты, которые учитывают данные как в DbSet.Local, так и в базе данных? - PullRequest
3 голосов
/ 20 июня 2011

Скажем, у меня есть таблица в базе данных с именем TestDB с таблицей с именем Table1, которая содержит два столбца

ID
Name

В этой таблице есть две строки:

ID 1 and Name 'Row1'
ID 2 and Name 'Row2'

Еслиэто мой код

var currObj = Table1.Where(o => o.Name.Contains("Row1")).FirstOrDefault();
currObj.Name = "Row1a";

var a = Table1.Where(o => o.Name.Contains("Row1a")).FirstOrDefault();
var b = Table1.Local.Where(o => o.Name.Contains("Row1a")).FirstOrDefault();

a вернет ноль, а b вернет значение.

если я сделаю это, хотя

var c = Table1.Where(o => o.Name.Contains("Row2")).FirstOrDefault();
var d = Table1.Local.Where(o => o.Name.Contains("Row2")).FirstOrDefault();

затемc вернет что-то, но d не вернет.

Для меня это кажется не интуитивным, поскольку данные могут быть в двух разных местах.Для каждого запроса, который я делаю, я должен искать в базе данных и объекте Local и объединять их вместе.Например, если это изменилось в локальном объекте, я должен принять это во внимание.Есть ли в Entity Framework какой-либо механизм для этого, который бы рассматривал ОБА данные в базе данных И локальные одновременно?

Так что, если бы я пошел

var e =  Table1.AMagicSolution.Where(o => o.Name.Contains("Row1a")).FirstOrDefault();
var f = Table1.AMagicSolution.Where(o => o.Name.Contains("Row2")).FirstOrDefault();

, тогда e и fоба возвращают что-то (f из базы данных и e из объекта Local)

Ответы [ 2 ]

5 голосов
/ 20 июня 2011

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

Если по какой-либо причине ваше приложение не знает, находится ли запись в локальном хранилище, вы всегда должны разделять запросы к локальному хранилищу и базе данных!Причины - производительность и ненужные обращения к базе данных.Используйте помощник, как в следующем примере, чтобы сначала запросить локальное хранилище, и только если запись отсутствует в локальном хранилище, запросите базу данных:

public static Table1 AMagicSolution(this IQueryable<Table1> query, string name)
{
    var item = Table1.Local.Where(t => t.Name.Contains(name)).FirstOrDefault(); 
    if (item != null)
    {
        item = Table1.Where(t => t.Name.Contains(name)).FirstOrDefault();
    }

    return item;
} 
1 голос
/ 20 июня 2011

Не сильно отличается от вашего другого вопроса.

Table1.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Unchanged)
    .Where(o => o.GetType() == typeof(Table1Type) 
           && o => o.Name.Contains("Row1a"))
    .FirstOrDefault();

Из документов : «EntityState является битовым полем, поэтому записи состояний для нескольких состояний могут быть получены за один вызов путем выполнения побитового ИЛИ нескольких значений EntityState.»

...