从 Entity Framework Core 的导航属性中选择对象列表

Posted

技术标签:

【中文标题】从 Entity Framework Core 的导航属性中选择对象列表【英文标题】:Select list of objects from navigation property in Entity Framework Core 【发布时间】:2021-10-20 13:33:05 【问题描述】:

我有以下具有导航属性的实体。

public class Member
    
        public Member()
        
            Id = 0;
            IsActive = true;
            BillDetails = new List<BillDetail>();            
        

        public int Id  get; set;         
        public string FirstName  get; set; 
        public string LastName  get; set; 
        public bool IsActive  get; set; 
        public int? OrgId  get; set;     
        public IList<BillDetail> BillDetails  get; set; 
    
    

我有一个通用存储库:

public abstract class BaseRepository<TEntity, TId> : IRepository<TEntity, TId> where TEntity : class
    
        private readonly IApplicationDbContext _db;

        public BaseRepository(IApplicationDbContext db)
        
            _db = db;
        

        public virtual void Add(TEntity entity)
        
            _db.Set<TEntity>().Add(entity);
            _db.Entry(entity).State = EntityState.Added;
        

        public virtual bool Update(TEntity entity)
        
            _db.Set<TEntity>().Attach(entity);
            _db.Entry(entity).State = EntityState.Modified;
            return true;
        

        public virtual bool Delete(TEntity entity)
        
            _db.Set<TEntity>().Remove(entity);
            _db.Entry(entity).State = EntityState.Deleted;
            return true;
        

        public virtual IQueryable<TEntity> Query()
        
            return _db.Set<TEntity>().AsQueryable();
        

        public virtual EntityEntry<TEntity> Entry(TEntity entity)
        
            return _db.Entry(entity);
        

        public void Attach(TEntity entity)
        
            if (entity == null || _db.Entry(entity).State != EntityState.Detached)
                return;

            _db.Set<TEntity>().Attach(entity);
        

        public void Detach(TEntity entity)
        
            if (entity == null)
                return;

            _db.Entry(entity).State = EntityState.Detached;
        

        public abstract Task<TEntity> FindAsync(TId id);
    

我想从我的服务类中获取以下类型的对象集合

public class MemberBill

    public int MemberId get; set;
    public decimal BillAmount get; set;

在我的服务类中,我有以下查询。现在如何从以下查询中获取对象列表 (MemberBill)?

var query = (_memberRepository.Query().Where(x => x.IsActive == true && x.OrgId == orgId)
                .Include(x => x.BillDetails.Where(y => y.IsActive == true))).AsNoTracking().AsQueryable();

            List<IList<BillDetail>> memberBills = query.Select(x => x.BillDetails).ToList();

            memberBills.Select(x => new MemberBill
            
                MemberId = x.
            ).ToList();

请帮我找出解决办法。

【问题讨论】:

你能把你的 billdetail 课贴出来吗? 【参考方案1】:

试试这个

var query = _memberRepository.Query()
.Where(x => x.IsActive == true && x.OrgId == orgId)
.Include(x => x.BillDetails.Where(y => y.IsActive == true))
.AsNoTracking()
.ToList();

var memberBills=new List<MemberBill>();

foreach(var m in query)

memberBills.Add( new MemberBill 
                  
                   MemberId= m.Id, 
                   BillAmount=m.BillDetails.Sum(i=> i.Amount)
                  );

【讨论】:

【参考方案2】:

离开这里的高性能解决方案。当前接受的答案使用大量内存和服务器资源。

var query = 
    from m in _memberRepository.Query()
    where m => m.IsActive == true && m.OrgId == orgId
    from bd in m.BillDetails.Where(bd => bd.IsActive == true)
    group bd by new  m.Id  into g
    select new MemberBill
    
        MemberId = g.Key.Id,
        BillAmount = g.Sum(x => x.Amount
    ;

var memberBills = query.ToList();

【讨论】:

你能评论一下吗? docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-5.0/… @Serge,他们只是做对了。您必须知道分组需要哪些列,而不仅仅是整个对象。 感谢您的及时回复和解释。我真的很感激。

以上是关于从 Entity Framework Core 的导航属性中选择对象列表的主要内容,如果未能解决你的问题,请参考以下文章

Entity Framework Core 删除包含已读取实体的实体

从 Entity Framework Core IQueryable<T> 获取 SQL 代码

如何使用 FromSqlRaw Entity Framework Core 3.1 从存储过程中返回多个 SELECT 集

如何使用 Entity Framework Core 将 SQL 数据从一个表传输到另一个表

Entity Framework Core 中的动态查询执行

Entity Framework Core 忽略 .Include(..) 而没有 .ToList(..) 间接