EF Core наследование сущностей из разных источников без дискриминатора - PullRequest
0 голосов
/ 07 декабря 2018

Я пытаюсь настроить два объекта, показанных ниже, с EF Core:

Пользователь:

public class User
{
    public int UserId { get; set; }
    public string Title { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    [Required]
    public string Email { get; set; }

    [NotMapped]
    public string FriendlyIdentifier
    {
        get
        {
            var name = $"{Name} {Surname}";
            if (!string.IsNullOrWhiteSpace(name))
                return name;
            else if (!string.IsNullOrWhiteSpace(Email))
                return Email;
            else
                return UserId.ToString();
        }
    }

    public ICollection<Booking> Bookings { get; set; }
}

UserDetails:

public class UserDetails : User
{
    public DateTime? LatestBookingDate { get; set; }
}

Причина этого заключается в том, что я хочу, чтобы пользователи могли получать данные с их последней датой бронирования без необходимости извлекать все данные о бронировании, а затем вручную определять последнюю дату бронирования в коде.Чтобы добиться этого, я создал представление SQL, которое выбирает самую последнюю дату бронирования, и я хочу привязать UserDetails к этому представлению.

У меня есть следующие настройки EF:

modelBuilder.Entity<User>(builder =>
{
    builder.ToTable("userdetails");
    builder.HasKey(x => x.UserId);
    builder.HasIndex(x => new { x.Name, x.Surname, x.Email });
});

modelBuilder.Query<UserDetails>()
    .ToView("view_userdetails");

Ноэто приводит к следующей ошибке при попытке выбрать сущность UserDetails:

'Невозможно установить' User 'в качестве базового типа' UserDetails '.Иерархии наследования не могут содержать сочетание типов сущностей и типов запросов. '

Я знаю, что есть расширение HasDiscriminator, как описано здесь: https://docs.microsoft.com/en-us/ef/core/modeling/relational/inheritance, но я не оченьесть дискриминатор, так как UserDetails это просто расширение User.

Есть ли какой-нибудь способ для меня, чтобы это работало?Я не хочу дублировать свойства User в UserDetails, потому что тогда есть две сущности, которые нужно поддерживать, когда что-то меняется.Я хотел бы сохранить наследство.

1 Ответ

0 голосов
/ 07 декабря 2018

Я хотел бы сохранить наследство.

Вы не можете (по крайней мере, не так, как сейчас).Это ясно указано в сообщении об исключении - оно говорит: «не может содержать смесь» и не дает вам предложения.

Что вы можете сделать, это переместить ваших текущих User учеников в новую базу non entity , non query type type и пусть оба User entity и UserDetails type query наследуют его, например:

public abstract class UserInfo
{
    public int UserId { get; set; }
    public string Title { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    [Required]
    public string Email { get; set; }

    [NotMapped]
    public string FriendlyIdentifier
    {
        get
        {
            var name = $"{Name} {Surname}";
            if (!string.IsNullOrWhiteSpace(name))
                return name;
            else if (!string.IsNullOrWhiteSpace(Email))
                return Email;
            else
                return UserId.ToString();
        }
    }

    public ICollection<Booking> Bookings { get; set; }
}

public class User : UserInfo { }

public class UserDetails : UserInfo
{
    public DateTime? LatestBookingDate { get; set; }
}

Это позволит вамсохранить общую модель в одном месте.Недостатком является то, что UserDetails не сможет использоваться в местах, где ожидается User, и его необходимо преобразовать (хотя, поскольку все общие свойства одинаковы, для AutoMapper это должно быть тривиальной задачей «auto»).

Обратите внимание, что для этого решения необходимо Ignore свойство навигации Bookings в типе запроса:

modelBuilder.Query<UserDetails>(builder =>
{ 
    builder.ToView("view_userdetails");
    builder.Ignore(e => e.Bookings);
});

или переместить его в объект User.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...