为了账号安全,请及时绑定邮箱和手机立即绑定

如何使列表和属性指向同一实体

如何使列表和属性指向同一实体

C#
慕桂英546537 2022-12-31 09:39:37
我是实体框架的新手,即使我知道如何在 Merise 中做到这一点,我也无法先使用代码来做到这一点。在实体用户中,我应该有一个外键“Promotion_Id”在实体促销中,我应该有一个指向用户实体的外键“Pilote_Id”。事情是这样的:我还有一个促销列表,它是促销中所有用户的列表。Pilote_Id 是该编队飞行员的 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; }但是我希望我的实体有一些一致性,所以..有没有正确的方法来实现这个?
查看完整描述

1 回答

?
慕妹3242003

TA贡献1824条经验 获得超6个赞

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


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


modelBuilder.Entity<User>()

   .HasOptional(u => u.Promotion)

   .WithRequired(p => p.Pilote)

   .Map(u => u.MapKey("PiloteId"); // EF6

   // .HasForeignKey("PilotId") // EF Core

这假设用户可能有促销活动,也可能没有促销活动,但所有促销活动都有试点。Promotion.Users 可能会按照惯例在促销表上使用 UserId 进行映射,但如果存在任何问题:


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


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


如果一个用户只能与 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;

   }

}

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


查看完整回答
反对 回复 2022-12-31
  • 1 回答
  • 0 关注
  • 51 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号