我在维护派生类型中的关系并使用LINQ查询它们时遇到了一些问题。请考虑以下情形。假设我具有以下层次结构:
public class Company
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
public abstract class Document
{
public int Id { get; set; }
public string DocType { get; set; }
public string Name { get; set; }
}
public class CompanyDoc : Document
{
public int CompanyId { get; set; }
public Company Company { get; set; }
}
public class PersonDoc : Document
{
public int PersonId { get; set; }
public Person Person { get; set; }
}
这意味着我有一个文档对象,并且文档的所有者可以是任何公司或任何人,因此我创建了2个派生文档公司doc和person doc。
我的问题是,保持这种关系是否可以,如果没有,那么维持这种等级制度的最佳方法是什么?
在ef core 2.1中,我可以使用TPH处理此层次结构。但是,如果要与所有者一起获取所有文档,将是linq查询。我已经尝试过以下一种,但它不起作用。
var doc = (from d in _context.Set<Document>()
join c in _context.Company on (d as CompanyDoc).CompanyId equals c.Id into cd
from cdoc in cd.DefaultIfEmpty()
join c in _context.Person on (d as PersonDoc).PersonId equals c.Id into pd
from pdoc in pd.DefaultIfEmpty()
select new {
d.Id,
d.Name,
Owner = cdoc.Name != null ? cdoc.Name : pdoc.Name
}).ToList()
您能通过分享您的想法来帮助我吗?请以这个为例。
答案 0 :(得分:0)
我认为您使查询过于复杂。 EF Core非常聪明地处理每个层次结构表(TPH)查询。通过将抽象类用作DbSet<T>
属性,您可以访问所有类型,并过滤出所需的内容。
因此,在您的示例中,DbContext将包含属性public DbSet<Document> Documents { get ; set; }
,以下查询将起作用。
//This returns all the documents - each document is of the correct type
//e.g PersonDocument or CompanyDocument
var allDocs = context.Documents.ToList();
//This would only return PersonDocuments - change the type for other versions
var personDocs = context.Documents.OfType<PersonDocument>().ToList();
EF Core会尽一切努力为您获取正确的数据和类型。很好用。
PS。如果您有我的书,请参阅TPH上的第7.8.2节,尤其是第201页。