Как составить список и свойство, указывающее на одну и ту же сущность - PullRequest
0 голосов
/ 25 апреля 2019

Я новичок в Entity Framework, и даже если я знаю, как это сделать в Merise, я не могу сделать это сначала с помощью кода.

У пользователя сущности у меня должен быть внешний ключ 'Promotion_Id'

В промо-акции организации у меня должен быть внешний ключ Pilote_Id, указывающий на сущность пользователя.

Вот в чем дело: у меня также есть список в рекламной акции, который представляет собой список всех пользователей в рекламной акции. Pilote_Id - это идентификатор пилота того формирования, который, конечно, пользователь.

Я попробовал следующее:

    public class User : EntityWithId
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        public string Password { get; set; }
        public string Phone { get; set; }
        public virtual Promotion Promotion { get; set; }     
    }
    public class Promotion : EntityWithNameAndId
    {
        //Site is another entity, the place where the promotion is 
        public virtual Site Site { get; set; }
        public List<User> Users { get; set; }
        public virtual User Pilote { get; set; }
    }

(Примечание. EntityWithId содержит только Id, а EntityWithNameAndId наследуется от EntityWithId и содержит только имя)

Но это приводит к тому, что в User есть два внешних ключа с именами Promotion_Id и Promotion_Id1.

Я уже сделал всю работу, изменив

public virtual User Pilote { get; set; }

с

public virtual Guid PiloteId { get; set; }

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

1 Ответ

1 голос
/ 26 апреля 2019

Вам, вероятно, потребуется использовать явное сопоставление для достижения этого:

В OnModelCreating () для вашего контекста:

modelBuilder.Entity<User>()
   .HasOptional(u => u.Promotion)
   .WithRequired(p => p.Pilote)
   .Map(u => u.MapKey("PiloteId"); // EF6
   // .HasForeignKey("PilotId") // EF Core

Это предполагает, что пользователь может иметь, а может и не иметьАкция, но во всех акциях есть Pilot.Поощрение, вероятно, будет отображаться в соответствии с соглашением, используя UserId в таблице продвижения, но если там есть какая-либо проблема:

Однако при таком подходе есть большая оговорка, касающаяся схемы, а не EF.,Нет ограничений / мер, которые гарантировали бы, что Пилот является одним из Пользователей, связанных с рекламной акцией.PiloteId может указывать на любого пользователя, и его промо-идентификатор может отличаться.

В любом случае логика управления пилотом должна выполняться с помощью кода, но это означает, что либо проверка идентификаторов на действительностькомбинации или что-то вроде:

Если пользователь может быть связан только с 1 промоушеном, и один пользователь в этом промоушене может быть пилотом, то вы можете рассмотреть возможность добавления флага для пользователя под названием «IsPilot».

Затем в акции:

public virtual ICollection<User> Users { get; set; } = new List<User>();
[NotMapped]
public User Pilote
{
   get { return Users.SingleOrDefault(u => u.IsPilote); }
   set 
   {   
      var newPilote = Users.Single(u => u.UserId == value.UserId); // Ensure the user nominated for Pilote is associated with this Promotion.
      var existingPilote = Pilote;
      if (existingPilote != null)
          existingPilote.IsPilote = false;
      newPilote.IsPilote = true;
   }
}

Если пользователи могут быть назначены для нескольких рекламных акций, вам нужно обновить схему и сопоставления, чтобы поддерживать отношение «многие ко многим» между пользователем и рекламными акциями, напримерв виде таблицы UserPromotions, содержащей UserId и PromotionId.В этом случае я хотел бы рассмотреть вопрос о назначении IsPilote в этой табличной / связывающей сущности, но опять же, для этого потребуется логика, обеспечивающая, чтобы правила составляли примерно 1 пилот-сигнал на повышение, а также мог ли пользователь быть пилотом для более чем одного повышения.

...