如何创建指向同一实体的列表和属性

问题描述 投票:0回答:1

我是实体框架的新手,即使我知道如何在Merise中做到这一点,我也不能先使用代码。

在实体用户中,我应该有一个外键'Promotion_Id'

在实体Promotion中,我应该有一个指向User实体的外键“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并且只包含一个名称)

但它只会导致在名为Promotion_Id和Promotion_Id1的用户中有2个外键。

我已经通过改变使整个事情发挥作用

public virtual User Pilote { get; set; }

public virtual Guid PiloteId { get; set; }

但我想在我的实体中保持一定的一致性..是否有正确的方法来实现这一目标?

c# entity-framework ef-code-first
1个回答
1
投票

您可能需要使用显式映射来实现此目的:

在您的上下文的OnModelCreating()中:

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

这假定用户可能或可能没有促销,但所有促销都有Pilot。 Promotion.Users可能会按照惯例使用促销表上的UserId映射确定,但如果有任何问题:

但是,这种方法存在一个很大的警告,它与模式有关,而不是EF。没有任何限制/保护措施可确保Pilot是与促销相关的用户之一。 PiloteId可以指向任何用户,该用户的promotionId可能不同。

在任何情况下,管理谁是飞行员的逻辑都需要通过代码完成,但这意味着要么检查有效组合的ID,要么类似:

如果用户只能与1个促销关联,并且该促销的一个用户可以是Pilot,那么您可以考虑向用户添加一个名为“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;
   }
}

如果可以将用户分配到多个促销,则您需要更新架构和映射以支持用户和促销之间的多对多关系,例如包含UserId和PromotionId的UserPromotions表。在这种情况下,我会考虑在此表/链接实体中分配IsPilote,但这又需要逻辑来确保每个促销约1个试验的规则,以及用户是否可以成为多个促销的试点。

© www.soinside.com 2019 - 2024. All rights reserved.