Условная нетерпеливая загрузка? - PullRequest
10 голосов
/ 15 сентября 2010

Я хочу загрузить сущность и ее дочерние элементы условно (я хочу загружать дочерние элементы только тогда, когда child.IsActive == true).Как выполнить следующее?

var parent = 
    from p in db.tblParents.Include("tblChildren") <-- where tblChildren.IsActive == true
    where p.PrimaryKey == 1
    select p;

ПРИМЕЧАНИЕ. Я не хочу возвращать анонимный тип.

Спасибо.

Ответы [ 3 ]

9 голосов
/ 15 сентября 2010

Один из способов сделать это:

var parent = from p in db.tblParents where p.PrimaryKey == 1
             select new {
                 Parent = p,
                 Children = p.tblChildren.Where(c => c.IsActive == true)
             }.ToList();


Однако, вам может не понравиться идея вернуть анонимный тип, тогда я бы посоветовал кодировать его следующим образом:

var parent = (from p in db.tblParents where p.PrimaryKey == 1).Single();
var childrens = ctx.Contacts.Where(c => c.ParentID == 1 && c.IsActive == true);
foreach (var child in childrens) {
   parent.tblChildren.Add(child);
}
2 голосов
/ 15 июня 2016

Чтобы применить фильтр, лучше использовать Явно загрузка вместе с Запрос () вместо Стремление загрузка:

var parent = db.tblParents.Find(1);
db.Entry(parent).Collection(p => p.tblChildren).Query().
    Where(child => child.IsActive).Load();

Метод Query предоставляет доступ к базовому запросу, который Entity Framework будет использовать при загрузке связанных сущностей. Также вам необходимо отключить отложенную загрузку для свойства навигации (удалить ключевое слово Virtual), иначе коллекция будет загружаться автоматически при отложенной загрузке, которая игнорирует ваш фильтр.

1 голос
/ 28 мая 2014

В Entity Framework 6 представлен перехват http://entityframework.codeplex.com/wikipage?title=Interception, который можно использовать для настройки SQL для фильтрации дочерних элементов.

Перед выполнением запроса добавьте перехватчик и удалите его, если он не имеет значения:

var interceptor = new ActiveTagsInterceptor();
DbInterception.Add(interceptor);

documents = context.Documents
                .AsQueryable()
                .Include(d => d.Tags)

DbInterception.Remove(interceptor);

Образец перехватчика, который добавляет «[Active] = 1 And» при загрузке тегов:

public class ActiveTagsInterceptor : IDbCommandInterceptor
{
    public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    {
    }

    public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    {
    }

    public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
        // [Tag] AS [Extent6] ON   => [Tag] AS [Extent6] ON [Extent6].[Active] = 1 And 
        const string pattern = "\\[Tag\\]\\sAS\\s\\[([\\w]+)\\]\\sON";
        const string replacement = "$& [$1].[Active] = 1 And ";
        command.CommandText = Regex.Replace(command.CommandText, pattern, replacement);
    }

    public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
    }

    public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
    }

    public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...