EF 4.1 - Model Relationships

痞子三分冷 提交于 2019-12-18 18:48:11

问题


I'm trying to create a quick ASP.NET MVC 3 application using the RC version of EF 4.1. I have two models:

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; }
}

and

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; }
}

I get the following error when trying to insert a new Race:

Unable to determine the principal end of an association between the types 'rcommander.Models.Race' and 'rcommander.Models.Address'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.

Shouldn't it recognize RaceId as the primary key of the Races table and AddressId as the FK to the Addresses table automatically? Am I missing something?

Thanks!


回答1:


The problem here seems to be that EntityFramework can't recognize where the foreing key is, as you are holding cross references in both objects. Not being sure what you want to achieve, I may suggest something like this:

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; }
}

Skipping reference to Race in second entity.




回答2:


The problem here is 1:1 relation between Address and Race! You probably want to map it as 1:N so you need to modify address to:

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 { ... }
}

If you want to use 1:1 then you can't use AddressId in Race but AddressId in Address must be foreign key of Race because entity framework can achive 1:1 only be "sharing" primary key.




回答3:


For one-to-one relationship, you need to add "[required]" attribute in the second class. See below:

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:


There is a good post: Associations in EF Code First CTP5: Part 2 – Shared Primary Key Associations

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




回答5:


It recognizes Id as the primary key by convention. So what you need to do:

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; }
}

The [Key] attribute indicates that it should be the PrimaryKey

If you don't want this, you need to rename your primary keys to simply public int Id {get; set; }




回答6:


I think it would be solved also like this... I assumed that an address is not required to be associated with a race, but a race must always be associated with an address. I had the same problem with Patients and Incidents and i solved it with InverseProperty which is actually the same with foreign key, but the other direction

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; }

}


来源:https://stackoverflow.com/questions/5352059/ef-4-1-model-relationships

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!