在相关DbSet上包含的DbSet上添加过滤器?

时间:2017-12-06 05:27:08

标签: c# entity-framework entity-framework-6 ef-code-first

以下是幕后的一些内容。

public class User : BaseTransactionModel
{
    public Guid UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class Transaction
{

    public int TransactionId { get; set; }
    public string TransactionName { get; set; }
    public int TransactionHistoryId { get; set; }

    public virtual TransactionHistory TransactionHistory { get; set; }
}

public class TransactionHistory
{
    public int TransactionHistoryId { get; set; }
    public DateTime CreatedDateTime { get; set; }
    public Guid UserId { get; set; }
    public int TransactionId { get; set; }

    public virtual ICollection<User> Users { get; set; }
    public virtual ICollection<Transaction> Transactions { get; set; }
}

public class BaseTransactionModel
{

    public int TransactionHistoryId { get; set; }
    public int TransactionId { get; set; }

    public virtual TransactionHistory TransactionHistory { get; set; }
    public virtual Transaction Transaction { get; set; }
}

通过以上实体,我尝试在指定日期从用户获取所有交易

所以我尝试在事务DbSet上同时包含用户 TransactionHistory

Context.Transaction
    .Include(t => t.User)
    .Include(t => t.TransactionHistory)
    ...

我想添加一个where子句,用于从事务历史实体中的日期过滤事务:

Context.Transaction
    .Include(t => t.User)
    .Include(t => t.TransactionHistory)
    .Where(t => t.TransactionHistory.CreatedDateTime <= StartDateFilter && t.TransactionHistory.CreatedDateTime >= EndDateFilter)

但无法这样做。由于TransactionHistory也是实体列表(或其所谓的任何内容)。

获得我想要达到的目标的可能解决方案是什么?

PS:我是EF的新手,标题可能会产生误导。如果是这样,请随时更新。

3 个答案:

答案 0 :(得分:0)

您可能需要重新考虑您的班级设计,例如

public class User
    {
        public Guid UserId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public virtual ICollection<Transaction> TransactionHistory { get; set; }
    }

    public class Transaction
    {    
        public int TransactionId { get; set; }
        public string TransactionName { get; set; }
        public DateTime CreatedDateTime { get; set; }
    }

然后要获得类似于您需要查询的交易,可以是这样的:

 var result = Context.User
                .Where(u => u.UserId == myguid)
                .Select(t => new
                {
                    UserId = t.UserId,
                    Transactions = t.TransactionHistory.Where(x => x.CreatedDateTime >= StartDateFilter && x.CreatedDateTime <= EndDateFilter)
                })
                .ToList();

答案 1 :(得分:0)

您正在寻找的是能够过滤包含的实体。

有两种方法可以过滤包含实体:

  • 使用投影(参见@majita答案)
  • 使用第三方库

免责声明:我是该项目的所有者Entity Framework Plus

EF + Query IncludeFilter允许轻松过滤包含的实体。

Context.Transaction
    .IncludeFilter(t => t.User)
    .IncludeFilter(t => t.TransactionHistory
        .Where(x => x.TransactionHistory.CreatedDateTime <= StartDateFilter && x.TransactionHistory.CreatedDateTime >= EndDateFilter))

在引擎盖下,图书馆完全是一个投影。

一个限制是所有Include,但现在即使未指定过滤器IncludeFilter,也会使用User进行调用。

维基:EF+ Query Include Filter

答案 2 :(得分:-1)

试试这个

Context.Transaction
    .Where(t => t.TransactionHistory.CreatedDateTime <= StartDateFilter && t.TransactionHistory.CreatedDateTime >= EndDateFilter)
.Select(x=> new {x.User,x.TransactionHistory});

或者这个

Context.Transaction
.Where(t => t.TransactionHistory.CreatedDateTime <= StartDateFilter && t.TransactionHistory.CreatedDateTime >= EndDateFilter)
.Include(t => t.User)
.Include(t => t.TransactionHistory)