EF 4.1 - Модельные отношения
Я пытаюсь создать быстрое приложение 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 в таблице адресов? Я что-то пропустил?
Спасибо!
Ответы
Ответ 1
Проблема здесь заключается в том, что 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; }
}
Пропуск ссылки на Race во втором объекте.
Ответ 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, то вы не можете использовать AddressId в Race, но AddressId в адресе должен быть внешним ключом Race, поскольку структура сущности может достигать 1:1, только "общий" первичный ключ.
Ответ 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
Ответ 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; }
Ответ 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; }
}