多个.Include in Repository

时间:2017-06-11 06:22:03

标签: c# entity-framework ef-code-first .net-core

首先,我在这里:

4个类之间有一些关系

项目有很多桥梁。

Bridge 有很多基金会。

基金会有很多 PierCap 和许多 PierColumn

Project.cs

public class Project
{
    public Project()
    {
        Bridges = new HashSet<Bridge>();

        StartDate = DateTime.Now;
        EndDate = DateTime.Now;
    }

    // Fields
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }

    // Calculated Fields
    public int BridgeCount => Bridges.Count;
    public int PierFoundationCount = 0;
    public int PierCapCount = 0;
    public int PierColumnCount = 0;

    // Relation To Children
    public virtual ICollection<Bridge> Bridges { get; private set; }
}

Bridge.cs

public class Bridge : BasicBaseEntityWithName
{
    public Bridge()
    {
        PierFoundations = new HashSet<PierFoundation>();
    }

    // Fields
    public int ProjectID { set; get; }
    public Project Project { set; get; }

    // Calculated Fields
    public int PierFoundationCount => PierFoundations.Count;
    public int PierCapCount => PierFoundations.Count;
    public int PierColumnCount => PierFoundations.Count;

    // Relation To Children
    public ICollection<PierFoundation> PierFoundations { get; private set; }
}

PierFoundation.cs:

public class PierFoundation : BasicBaseEntityWithName
{
    public PierFoundation()
    {
        PierCaps = new HashSet<PierCap>();
        PierColumns = new HashSet<PierColumn>();
    }

    // Fields
    public float Length { set; get; }

    // Calculated Fields
    public int PierColumnCount => PierColumns.Count;
    public int PierCapCount => PierCaps.Count;
    public float FoundationQty => (Length * Width * Height);

    // Relations To Parents
    public int BridgeID { set; get; }
    public Bridge Bridge { set; get; }

    // Relations To Children
    public ICollection<PierCap> PierCaps { get; set; }
    public ICollection<PierColumn> PierColumns { get; set; }
}

PierColumn.cs:

public class PierColumn : BaseEntityNoName
{
    // Fields
    public float Diameter { set; get; }

    // Relations To Parents
    public int PierFoundationID { set; get; }
    public PierFoundation PierFoundation { set; get; }
}

PierCap.cs:

public class PierCap : BaseEntityNoName
{
    // Fields
    public float CapWidth { set; get; }

    // Relations To Parents
    public int PierFoundationID { set; get; }
    public PierFoundation PierFoundation { set; get; }
}

BaseEntityNoName.cs:

public class BaseEntityNoName
{
    public BaseEntityNoName()
    {
        AddedBy = Core.General.Global.CurrentUseId;
        AddedDate = DateTime.Now;
    }
    public int Id { get; set; }

    public DateTime AddedDate { get; set; }
    public int AddedBy { get; set; }

    // Becuase they will not appear at new, they will be nullable
    public DateTime? ModifiedDate { get; set; }
    public int? ModifiedBy { get; set; }
}

BasicBaseEntityWithName.cs:

public class BasicBaseEntityWithName : BaseEntityNoName
{
    public string Name { get; set; }
}

添加,我的存储库中有方法

public IEnumerable<TEntity> Include(params Expression<Func<TEntity, object>>[] includeExpressions)
{
    DbSet<TEntity> dbSet = Context.Set<TEntity>();

    IEnumerable<TEntity> query = null;
    foreach (var includeExpression in includeExpressions)
    {
        query = dbSet.Include(includeExpression);
    }

    return query ?? dbSet;
}

我的问题是:

Q1 即可。当我使用Include相关实体(PierFoundation,PierCap,PierColumn)时,我不会全部拿到它们!所以,当我输入:

    PierFoundations = CurrentUnitOfWork.PierFoundationRepository.Include(x => x.PierColumns, x => x.PierCaps);

我只收到了 PierFoundation PierCap ,但没有收到 PierColumn

这里有什么问题?。我想要检索所有这三个数据中的所有数据。

Q2 即可。在项目类中,我有四个计算字段:

    BridgeCount ,由 Bridges.Count解析

  • PierFoundationCount

  • PierCapCount

  • PierColumnCount

最后三个,我不知道怎么弄它们,因为它们与项目没有直接关系

BTW:我正在使用EF Core 2

1 个答案:

答案 0 :(得分:3)

这两个问题是无关的,所以只回答主要问题(如帖子标题所示) Q1

  

当我使用Include相关实体(PierFoundation,PierCap,PierColumn)时,我不能全部获取它们。

由您的存储库方法实现中的以下行引起:

query = dbSet.Include(includeExpression);

与许多LINQ方法一样,在与其他调用链接时使用Include方法返回值非常重要,正如您所看到的,此代码仅存储最后 Include调用,因此您正在观察的行为。

可以通过改变实现来解决这个问题:

var query = Context.Set<TEntity>().AsQueryable();
foreach (var includeExpression in includeExpressions)
    query = query.Include(includeExpression); // Note the usage of query variable
return query;

或只是

return includeExpresions.Aggregate(Context.Set<T>().AsQueryable(), (q, e) => q.Include(e)); 

但请注意,EF Core使用不同的方法来包含无法用ThenInclude表示的嵌套数据级别(Expression<Func<T, object>>),因此您可以考虑从存储库中公开IQueryable<TEntity>返回方法,使用EF Core提供的Include / ThenInclude扩展方法。

如果 Q2 ,请考虑将其发布在单独的SO问题(帖子)中。