EF Core 3.1和這樣的主-從模型:
public class MyMaster
{
public Guid Id { get; set; }
public string Category { get; set; }
public List<MyDetail> MyDetails { get; set; }
}
public class MyDetail public Guid Id { get; set; }
public Guid MasterId { get; set; }
public bool IsDeleted { get; set; }
我想選擇某些類別中的所有主記錄以及未標記為洗掉的細節。另外,如果某個主記錄的所有細節都被標記為洗掉,那么這個主記錄就不會被回傳。基本上,我想運行這樣一個簡單的選擇:
select * from MyMaster m
inner join MyDetail d on m. Id = d.MasterId and d.IsDeleted = 0
where m.Category= 'foo'
我嘗試了這樣的LINQ方法,但是它也回傳了被洗掉的詳細記錄:
var result = await dbContext.MyMasters
.Include(m => m.MyDetails)
.Where(m => m.Category = 'foo')
.Join(dbContext.MyDetails.Where(d => !d.IsDeleted), m => m.Id, d => d.MasterId, (m, d) => m)
.ToListAsync()。
LINQ方法的查詢應該是怎樣的?
CodePudding
如果你需要的資料只是用于查詢,可以通過Select輕松獲取:
var result = await dbContext.MyMasters
.Where(m => m.Category = 'foo')
.Select(m => new MyMaster
{
Id = m.Id,
Category = m.Category,
MyDetails = m.MyDetails.Where(d => !d.IsDeleted).ToList()
})
.ToListAsync()。
uj5u.com熱心網友回復:
你的代碼是真實的,但我寫并測驗了這些查詢,并顯示了結果,它對我來說是有效的。
var result = await _dBContext.MyMasters
.Include(m => m.MyDetails)
.Where(m => m.Category == "foo")
.Join(_dBContext.MyDetails.Where(d => !d.IsDeleted)。
m => m.Id,
d => d.MasterId,
(m, d) => new {
MasterId = m.Id,
Category = m.Category,
DetailId = d.Id,
IsDeleted = d.IsDeleted,
})
.ToListAsync()。
var result2 = from m in _dBContext.MyMasters.Include(m => m.MyDetails)
join d in _dBContext.MyDetails on m.Id equals d.MasterId
where m.Category == "foo"/span> && !d.IsDeleted
select new {
MasterId = m.Id,
Category = m.Category,
DetailId = d.Id,
IsDeleted = d.IsDeleted,
};
你嘗試在加入兩個集合后選擇新的型別。如果你從MyDetails的主人那里得到集合,你會得到所有的專案,因為它沒有被過濾,它只是所有的導航專案。
uj5u.com熱心網友回復:
看起來實際問題是如何過濾相關物體。
過濾包括
在EF Core 5及以后的版本中,這是用過濾的包括:
var result = await dbContext.MyMasters
.Include(m => m.MyDetails.Where(d=>!d.IsDeleted))
.Where(m => m.Category = 'foo')
.ToListAsync()。
全球查詢過濾器
另一個在以前的版本中也適用的選項是使用全域查詢過濾器,以確保洗掉的物體永遠不會通過該DbContext加載,即使是意外的情況:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MyDetail>().HasQueryFilter(p => !p.IsDeleted)。
...
}
這樣一來,下面的查詢將只加載活動的記錄 :
var result = await dbContext.MyMasters
.Include(m => m.MyDetails)
.Where(m => m.Category = 'foo')
.ToListAsync()。
全域查詢過濾器會影響整個DbContext,這是完全正確的。DbContext并不是資料庫的模型,而物體也不是表。擁有不同的 DbContext 的物體和針對同一資料庫的不同配置,處理特定的場景/用例(如果你喜歡 DDD,則為有界的背景關系)是完全可以的。
在這種情況下,大多數應用程式將使用帶有全域查詢過濾器的 DbContext,而管理頁面將使用允許訪問所有記錄的不同 DbContext
。轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/309850.html
標籤:

