EF 4.1 - Модельные отношения - PullRequest
21 голосов
/ 18 марта 2011

Я пытаюсь создать быстрое приложение ASP.NET MVC 3 с использованием RC-версии EF 4.1. У меня есть две модели:

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

При попытке вставить новую расу я получаю следующую ошибку:

Невозможно определить основной конец ассоциации между типами 'rcommander.Models.Race' и 'Rcommander.Models.Address. Основной конец этой ассоциации должен быть явно настроенным с использованием либо отношения свободно API или данные аннотаций.

Не должен ли он автоматически распознавать RaceId в качестве первичного ключа таблицы Races и AddressId в качестве FK для таблицы адресов? Я что-то упустил?

Спасибо!

Ответы [ 6 ]

21 голосов
/ 18 марта 2011

Проблема здесь заключается в том, что EntityFramework не может распознать, где находится ключ foreing, поскольку вы держите перекрестные ссылки в обоих объектах.Не зная, чего вы хотите достичь, я могу предложить что-то вроде этого:

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

Пропуск ссылки на Расу во второй сущности.

18 голосов
/ 18 марта 2011

Проблема здесь в соотношении 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, то вы не можете использовать AddressId в Race, но AddressId в Address должен быть внешним ключом Race, потому что структура сущностей может достигать 1: 1 только как «общий» первичный ключ.

8 голосов
/ 16 июля 2012

Для отношений один-к-одному необходимо добавить атрибут «[обязательный]» во второй класс. Смотрите ниже:

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

}
5 голосов
/ 21 апреля 2011

Есть хороший пост: Ассоциации в 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

4 голосов
/ 18 марта 2011

Он распознает 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; }

0 голосов
/ 21 августа 2012

Я думаю, что это будет решено также, как это ... Я предположил, что адрес не обязательно должен быть связан с гонкой, но гонка всегда должна быть связана с адресом.У меня была такая же проблема с пациентами и инцидентами, и я решил ее с помощью 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; }

}
...