Я лично использую свободный API в EF 4.1 для настройки всех своих сущностей, когда я не чувствую, что соглашения по умолчанию меня поймут, поэтому я отвечу, используя свободный API.
Вот как я бы настроил модели:
public class Member
{
public Member()
{
AuthenticationTokens = new List<AuthenticationToken>();
}
public int MemberId { get; set; }
public virtual Email PrimaryEmail { get; set; }
public virtual ICollection<AuthenticationToken> AuthenticationTokens { get; set; }
}
public class AuthenticationToken
{
public int AuthenticationTokenId { get; set; }
public virtual Email Email { get; set; }
}
public class Email
{
public int EmailId { get; set; }
}
И это мой контекст и свободная конфигурация:
public class ExampleApplicationContext : DbContext
{
public ExampleApplicationContext()
: base("ExampleApplicationConnection")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// No cascade on delete because the primary email may be held by an authentication token.
modelBuilder.Entity<Member>()
.HasOptional(x => x.PrimaryEmail)
.WithOptionalDependent()
.Map(x =>
{
x.MapKey("EmailId");
})
.WillCascadeOnDelete(false);
// Cascade on delete because an authentication token not associated with a Member makes no sense.
modelBuilder.Entity<Member>()
.HasMany(x => x.AuthenticationTokens)
.WithRequired()
.Map(x =>
{
x.MapKey("MemberId");
})
.WillCascadeOnDelete();
// No cascade on delete because an email may be held by a Member.
modelBuilder.Entity<AuthenticationToken>()
.HasOptional(x => x.Email)
.WithOptionalDependent()
.Map(x =>
{
x.MapKey("EmailId");
})
.WillCascadeOnDelete(false);
}
public DbSet<Member> Members { get; set; }
}
Я сделаю все возможное, чтобы объяснить, почему я разработал это так. Прежде всего, кажется, что в вашей модели Member
должен быть корневым агрегатом (босс других сущностей). Я имею в виду, что Authentication Token
не имеет смысла, если он не принадлежит конкретному Member
. Email
также не имеет смысла в одиночку, если только он не принадлежит Member
или не принадлежит AuthenticationToken
. По этой причине AuthenticationToken
не имеет свойства, чтобы выяснить, к чему Member
он прикреплен (чтобы это выяснить, сначала нужно Member
, а затем просто посмотреть на его коллекцию). По сути, все вращается вокруг объекта Member
. Без Member
невозможно создать AuthenticationToken
. А без Member
или AuthenticationToken
невозможно создать Email
.
Я не совсем уверен, насколько вас устраивает свободный API в EF 4.1, поэтому, если у вас есть какие-либо вопросы, оставьте комментарий, и я сделаю все возможное, чтобы ответить на них. Я также включил небольшой пример приложения, которое использовал для построения и проверки модели, представленной выше. Если вы хотите запустить программу (это небольшое консольное приложение), вам просто нужно изменить строку подключения в App.config, чтобы она указала на ваш экземпляр SQL Server.
Одна вещь, которая касается меня, это то, что Email
может принадлежать как Member
, так и AuthenticationToken
. Мое беспокойство связано с тем, что мне пришлось установить несколько интересных каскадных удалений. Однако я не знаю всех ваших требований, и эта настройка, кажется, работает нормально, поэтому это может не быть проблемой.
Пример консольного приложения