Поддерживать отношения в производном типе в EF Core - PullRequest
0 голосов
/ 20 марта 2019

У меня возникла проблема с поддержанием отношений в производных типах и запросом их с помощью 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 производных документа company doc & person doc.

У меня вопрос: можно ли поддерживать такие отношения, если нет, то как лучше всего поддерживать такую ​​иерархию?

В ядре 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()

Не могли бы вы помочь мне, поделившись своими мыслями. Пожалуйста, примите это как гипотетический пример.

1 Ответ

0 голосов
/ 20 марта 2019

Я думаю, вы слишком усложняете запрос.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.Если у вас есть моя книга, посмотрите раздел 7.8.2, особенно страницу 201, по TPH.

...