【问题标题】:EF 4.1 - Model RelationshipsEF 4.1 - 模型关系
【发布时间】:2011-07-18 03:31:49
【问题描述】:

我正在尝试使用 EF 4.1 的 RC 版本创建一个快速的 ASP.NET MVC 3 应用程序。我有两个模型:

public class Race
{
    public int RaceId { get; set; }
    public string RaceName { get; set; }
    public string RaceDescription { get; set; }
    public DateTime? RaceDate { get; set; }
    public decimal? Budget { get; set; }
    public Guid? UserId { get; set; }
    public int? AddressId { get; set; }

    public virtual Address Address { get; set; }
}

public class Address
{
    public int AddressId { get; set; }
    public string Street { get; set; }
    public string StreetCont { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }

    public virtual Race Race { get; set; }
}

尝试插入新 Race 时出现以下错误:

无法确定本金端 类型之间的关联 'rcommander.Models.Race' 和 'rcommander.Models.Address'。这 该关联的主体端必须 使用任一显式配置 关系流式 API 或数据 注释。

它不应该自动将 RaceId 识别为 Races 表的主键,将 AddressId 识别为 Addresses 表的 FK 吗?我错过了什么吗?

谢谢!

【问题讨论】:

    标签: asp.net-mvc-3 entity-framework-4 entity-relationship ef-code-first entity-framework-4.1


    【解决方案1】:

    这里的问题似乎是 EntityFramework 无法识别外键的位置,因为您在两个对象中都持有交叉引用。不确定你想要达到什么目标,我可能会建议这样的事情:

    public class Race
    {
      public int RaceId { get; set; }
      public string RaceName { get; set; }
      public string RaceDescription { get; set; }
      public DateTime? RaceDate { get; set; }
      public decimal? Budget { get; set; }
      public Guid? UserId { get; set; }
    
      public int? AddressId { get; set; }
      public virtual Address Address { get; set; }
    }
    
    public class Address
    {
      public int AddressId { get; set; }
      public string Street { get; set; }
      public string StreetCont { get; set; }
      public string City { get; set; }
      public string State { get; set; }
      public string ZipCode { get; set; }
    }
    

    在第二个实体中跳过对 Race 的引用。

    【讨论】:

    • 不会从地址中删除导航可能性吗?
    • 是的,它会从地址中删除导航可能性,并将其映射为我在回答中描述的一对多关系。
    • 那么有没有办法在交叉引用中实现(可能通过属性)关系?
    • 为什么你真的需要 public int?地址 ID { 获取;放; }?
    【解决方案2】:

    这里的问题是地址和种族之间的 1:1 关系!您可能希望将其映射为 1:N,因此您需要将地址修改为:

    public class Address
    {
      public int AddressId { get; set; }
      public string Street { get; set; }
      public string StreetCont { get; set; }
      public string City { get; set; }
      public string State { get; set; }
      public string ZipCode { get; set; }
    
      public virtual ICollection<Race> Races { ... }
    }
    

    如果要使用 1:1 则不能在 Race 中使用 AddressId 但 Address 中的 AddressId 必须是 Race 的外键,因为实体框架可以实现 1:1 只能是“共享”主键。

    【讨论】:

    • 您能否更新您的答案以显示如何通过共享主键使用 1:1?我想有一个像这样的双向访问方式:Race.Address 和 Address.Race。如果可能,请在您的示例中保留种族和地址。谢谢。
    • @Leniel:检查这个答案:stackoverflow.com/questions/5388077/…我想这就是你要找的。​​span>
    【解决方案3】:

    对于一对一的关系,需要在第二个类中添加“[required]”属性。见下文:

    public class Race
    {
      public int RaceId { get; set; }
      public string RaceName { get; set; }
      public string RaceDescription { get; set; }
      public DateTime? RaceDate { get; set; }
      public decimal? Budget { get; set; }
      public Guid? UserId { get; set; }
    
      public int? AddressId { get; set; }
      public virtual Address Address { get; set; }
     }
    
    public class Address
    {
     public int AddressId { get; set; }
     public string Street { get; set; }
     public string StreetCont { get; set; }
     public string City { get; set; }
     public string State { get; set; }
     public string ZipCode { get; set; }
    
     [required]
     public Race Race { get; set; }
    
    }
    

    【讨论】:

      【解决方案4】:

      有一篇好帖子:EF Code First CTP5 中的关联:第 2 部分 – 共享主键关联

      http://weblogs.asp.net/manavi/archive/2010/12/19/entity-association-mapping-with-code-first-one-to-one-shared-primary-key-associations.aspx

      【讨论】:

      • "将我们的关联变成一对一的一种方法是使它们成为双向的。也就是说,向 User 类型的 Address 类和 Shipment 类型的另一个添加一个新的导航属性。" - 这似乎不起作用。我收到“无法确定类型之间关联的主体端......必须使用关系流式 API 或数据注释显式配置此关联的主体端。”
      【解决方案5】:

      它按照约定将 Id 识别为主键。那么你需要做什么:

      public class Race
      {
          [Key]
          public int RaceId { get; set; }
          public string RaceName { get; set; }
          public string RaceDescription { get; set; }
          public DateTime? RaceDate { get; set; }
          public decimal? Budget { get; set; }
          public Guid? UserId { get; set; }
          public int? AddressId { get; set; }
      
          public virtual Address Address { get; set; }
      }
      and
      
      public class Address
      {
          [Key]
          public int AddressId { get; set; }
          public string Street { get; set; }
          public string StreetCont { get; set; }
          public string City { get; set; }
          public string State { get; set; }
          public string ZipCode { get; set; }
      
          [ForeignKey("RaceId")] // Maybe telling it what the ForeignKey is will help?
          public virtual Race Race { get; set; }
      }
      

      [Key]属性表示应该是PrimaryKey

      如果您不想这样,您需要将主键重命名为简单的public int Id {get; set; }

      【讨论】:

      • 使用任何一种方法都会出现同样的错误。如果这很重要,我在 Global.asax 的 Application_Start 中有我的 DB Initializer 到 DropCreateDatabaseIfModelChanges。
      • 嗯...检查我的更新.. 也许 ForeignKeyAttribute 是你需要的?
      • Isnt InverseProperty("RaceId") 这里需要什么,而不是 ForeignKey?
      • 假设我们有 InverseProperty("RaceId") - 你能有: var address = new Address(); var race = new Race(){Address = address} - 然后通过address.Race获得比赛?
      【解决方案6】:

      我认为也可以这样解决...我假设地址不需要与比赛相关联,但比赛必须始终与地址相关联。 我对患者和事件有同样的问题,我用 InverseProperty 解决了它,这实际上与外键相同,但方向相反

      public class Race
      {
        public int RaceId { get; set; }
        public string RaceName { get; set; }
        public string RaceDescription { get; set; }
        public DateTime? RaceDate { get; set; }
        public decimal? Budget { get; set; }
        public Guid? UserId { get; set; }
      
        public int AddressId { get; set; }
      
        [ForeignKey("AddressId")]
        public virtual Address Address { get; set; }
       }
      
      public class Address
      {
       public int AddressId { get; set; }
       public string Street { get; set; }
       public string StreetCont { get; set; }
       public string City { get; set; }
       public string State { get; set; }
       public string ZipCode { get; set; }
      
       public int? RaceId { get; set; }
       [InverseProperty("RaceId")]
       public Race Race { get; set; }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多