简体   繁体   English

在EF Core中维护派生类型中的关系

[英]Maintain relationship in derived type in EF Core

I am facing some problem to maintain the relationship in derived types and query them using LINQ. 我在维护派生类型中的关系并使用LINQ查询它们时遇到了一些问题。 Please consider the following scenario. 请考虑以下情形。 Let's say I have the below hierarchy: 假设我具有以下层次结构:

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; }
}

That means I have a document object and the owner of the document can be any company or any person so I create 2 derived document company doc & person doc. 这意味着我有一个文档对象,文档的所有者可以是任何公司或任何人,因此我创建了两个派生文档公司文档和人员文档。

My question is, is it ok to maintain a relationship like this way, if not then what is the best approach to maintain this kind of hierarchy? 我的问题是,以这种方式保持关系是否可以,如果没有,那么维持这种等级制度的最佳方法是什么?

In ef core 2.1 I can handle this hierarchy using TPH. 在ef core 2.1中,我可以使用TPH处理此层次结构。 But If I want to get all the document along with the owner what will be the linq query. 但是,如果要与所有者一起获取所有文档,将是linq查询。 I have tried with below one but it does not work. 我已经尝试过以下一种,但它不起作用。

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()

Can you please help me by sharing your thoughts. 您能否通过分享您的想法来帮助我。 Please take this as a hypothetical example. 请将此作为假设示例。

I think you are overcomplicating the query. 我认为您使查询过于复杂。 EF Core is quite clever on how it handles Table per hierarchy (TPH) queries. EF Core非常聪明地处理每个层次结构表(TPH)查询。 By using the abstract class as the DbSet<T> property you can access all the types, and filter out what you want. 通过将抽象类用作DbSet<T>属性,您可以访问所有类型,并过滤出所需的内容。

So, in your example the DbContext would contain a property public DbSet<Document> Documents { get ; set; } 因此,在您的示例中,DbContext将包含一个属性public DbSet<Document> Documents { get ; set; } public DbSet<Document> Documents { get ; set; } public DbSet<Document> Documents { get ; set; } and the following queries would work. 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 does all the hard work to get the correct data and type for you. EF Core会尽一切努力为您获取正确的数据和类型。 It's pretty nice to use. 很好用。

PS. PS。 If you have my book Entity Framework Core in Action then I cover TPH in section 7.8.2, especially page 201. 如果您有一本书《 实体框架核心在行动》,那么我将在7.8.2节(尤其是第201页)中介绍TPH。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM