Как разделить большую таблицу на несколько отдельных типов, используя EF-Code-First
Я пытаюсь разделить большую таблицу на несколько отдельных типов.
Я следую примеру здесь: http://weblogs.asp.net/manavi/archive/2011/04/24/associations-in-ef-4-1-code-first-part-4-table-splitting.aspx?CommentPosted=true
Он работает для основного типа и подтипа, но не работает, когда я использую несколько типов. Я получил ошибку
Типы сущностей 'CampaginFeedback' и 'CampaignSurvey' не могут совместно использовать таблицу 'Campaign', поскольку они не относятся к одной и той же иерархии типов или не имеют действительного отношения один к одному внешнего ключа с соответствующими первичными ключами между ними.
Вот упрощенные версии моих занятий:
public class Campaign {
[Key]
public int CampaignId {get;set;}
public string Name {get;set;}
public virtual CampaignSurvey Survey {get;set;}
public virtual CampaignFeedback Feedback {get;set;}
}
public class CampaignSurvey {
[Key]
public int CampaignId {get;set;}
public string Question {get;set;}
public string Answer {get;set;}
}
public class CampaignFeedback {
[Key]
public int CampaignId {get;set;}
public string Feedback {get;set;}
}
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Campaign>().HasRequired(c => c.Survey).WithRequiredPrincipal();
modelBuilder.Entity<Campaign>().HasRequired(c => c.Feedback).WithRequiredPrincipal();
modelBuilder.Entity<Campaign>().ToTable("Campaign");
modelBuilder.Entity<CampaignSurvey>().ToTable("Campaign");
modelBuilder.Entity<CampaignFeedback>().ToTable("Campaign");
}
2 ответа
Редактировать: разделить таблицу на более чем две сущности в коде первым очень проблематично. Работает без проблем при использовании EDMX.
Чтобы это работало, вы должны убедиться, что каждая сущность, используемая для разделения таблицы, имеет действительное отношение один к одному со всеми другими сущностями, используемыми для разделения таблицы. Это также означает порчу вашей модели со свойствами навигации и, кроме того, обеспечение того, чтобы при сохранении все свойства навигации, указывающие на один и тот же тип сущности, ссылались на один и тот же экземпляр (в противном случае вы получите исключение во время вызова SaveChanges
).
Таким образом, решение для вашего примера должно быть примерно таким:
public class Campaign {
[Key]
public int CampaignId {get;set;}
public string Name {get;set;}
public virtual CampaignSurvey Survey {get;set;}
public virtual CampaignFeedback Feedback {get;set;}
}
public class CampaignSurvey {
[Key]
public int CampaignId {get;set;}
public string Question {get;set;}
public string Answer {get;set;}
public virtual CampaignFeedback Feedback {get;set;}
}
public class CampaignFeedback {
[Key]
public int CampaignId {get;set;}
public string Feedback {get;set;}
}
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Campaign>().HasRequired(c => c.Survey).WithRequiredPrincipal();
modelBuilder.Entity<Campaign>().HasRequired(c => c.Feedback).WithRequiredPrincipal();
modelBuilder.Entity<CampaignSurvey>().HasRequired(c => c.Feedback).WithRequiredPrincipal();
modelBuilder.Entity<Campaign>().ToTable("Campaign");
modelBuilder.Entity<CampaignSurvey>().ToTable("Campaign");
modelBuilder.Entity<CampaignFeedback>().ToTable("Campaign");
}
Я даже не уверен, как это будет работать в реальном сценарии. Вы можете найти некоторые другие проблемы при его использовании.
Что-то, что я нашел, что работает, - это создать представление и указать на это ваши дополнительные сущности.