c# - 如何在 EF Core 2 中为 .ThenInclude 编写 Repository 方法

标签 c# lambda .net-core entity-framework-core repository-pattern

我正在尝试为 Entity Framework Core 2.0 编写一个存储库方法,该方法可以使用 .ThenInclude 处理返回的子属性集合,但我在使用第二个表达式时遇到了问题。这是 .Include 的工作方法,它将返回实体的子属性(您提供 lambda 列表)。

public T GetSingle(Expression<Func<T, bool>> predicate, params Expression<Func<T, object>>[] includeProperties)
{
    IQueryable<T> query = _context.Set<T>();
    foreach (var includeProperty in includeProperties)
    {
        query = query.Include(includeProperty);
    } 

    return query.Where(predicate).FirstOrDefault();
}

现在,我尝试编写一种方法,该方法将接受两个表达式的元组并将它们提供给 .Include(a => a.someChild).ThenInclude(b => b.aChildOfSomeChild) 链。这不是一个完美的解决方案,因为它只处理一个 child 的一个 child ,但这是一个开始。

public T GetSingle(Expression<Func<T, bool>> predicate, params Tuple<Expression<Func<T, object>>, Expression<Func<T, object>>>[] includeProperties)
{
    IQueryable<T> query = _context.Set<T>();
    foreach (var includeProperty in includeProperties)
    {
         query = query.Include(includeProperty.Item1).ThenInclude(includeProperty.Item2);              
    }

    return query.Where(predicate).FirstOrDefault();
}

Intellisense 返回错误“无法从用法中推断出类型,请尝试明确指定类型”。我有一种感觉,因为 Item2 中的表达式需要归类为与 Item1 有某种关联,因为它需要知道它具有的子关系。

编写这样的方法有什么想法或更好的技术吗?

最佳答案

我在网上找到了这个存储库方法,它完全符合我的要求。 Yared 的回答很好,但并非一直如此。

/// <summary>
/// Gets the first or default entity based on a predicate, orderby delegate and include delegate. This method default no-tracking query.
/// </summary>
/// <param name="selector">The selector for projection.</param>
/// <param name="predicate">A function to test each element for a condition.</param>
/// <param name="orderBy">A function to order elements.</param>
/// <param name="include">A function to include navigation properties</param>
/// <param name="disableTracking"><c>True</c> to disable changing tracking; otherwise, <c>false</c>. Default to <c>true</c>.</param>
/// <returns>An <see cref="IPagedList{TEntity}"/> that contains elements that satisfy the condition specified by <paramref name="predicate"/>.</returns>
/// <remarks>This method default no-tracking query.</remarks>
public TResult GetFirstOrDefault<TResult>(Expression<Func<TEntity, TResult>> selector,
                                          Expression<Func<TEntity, bool>> predicate = null,
                                          Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
                                          Func<IQueryable<TEntity>, IIncludableQueryable<TEntity, object>> include = null,
                                          bool disableTracking = true)
{
    IQueryable<TEntity> query = _dbSet;
    if (disableTracking)
    {
        query = query.AsNoTracking();
    }

    if (include != null)
    {
        query = include(query);
    }

    if (predicate != null)
    {
        query = query.Where(predicate);
    }

    if (orderBy != null)
    {
        return orderBy(query).Select(selector).FirstOrDefault();
    }
    else
    {
        return query.Select(selector).FirstOrDefault();
    }
}

用法:

var affiliate = await affiliateRepository.GetFirstOrDefaultAsync(
    predicate: b => b.Id == id,
    include: source => source
        .Include(a => a.Branches)
        .ThenInclude(a => a.Emails)
        .Include(a => a.Branches)
        .ThenInclude(a => a.Phones));

关于c# - 如何在 EF Core 2 中为 .ThenInclude 编写 Repository 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46374252/

相关文章:

.net - 默认的 netcore docker-compose 模板如何工作?

c# - Azure Function App Azure 服务总线触发器触发两次

使用 MySql 的 C# Windows 应用程序

java - 类型变量、方法内联和 "Bad return type in lambda expression"

结合 lambda 和 multi-catch 子句时出现 Java 错误?

c# - 如何在asp.net core中的startup.cs文件的configure方法中更改作用域服务的属性值

c# - 在c#中检查线程是否正在运行

c# - IIS Express 8 - 最大允许长度

ruby - 什么是 proc 和 lambda?请实际例子

.net-core - 面向 ARM64 的 .NET Core 3.0 发布