2014-02-17 3 views
3

У меня есть таблица с именем SystemAccount, которая (до недавнего времени) имела на ней MasterAccountID, которая указывала бы на ее родительскую учетную запись (очевидно,). Мой клиент теперь сказал мне, что иногда бывает, что у учетной записи могут быть две родительские учетные записи (у них никогда не было больше). Я пытаюсь выполнить настройку в классе SystemAccount, но это не создает отношения, которые я хочу.Два отношения «один ко многим» в одной таблице

Вот часть кода класса:

[ForeignKey("MasterAccount")] 
public int? MasterAccountID { get; set; } 

[ForeignKey("SecondMasterAccount")] 
public int? SecondMasterAccountID { get; set; } 

public virtual SystemAccount MasterAccount { get; set; } 

public virtual SystemAccount SecondMasterAccount { get; set; } 

public virtual List<SystemAccount> AllSubAccounts { get; set; } 

public virtual List<SystemAccount> SecondarySubAccounts { get; set; } 

Когда я делаю это я получаю 4 FKs в таблице, 2 из которых генерируется автоматически (SystemAccount_ID и SystemAccount_ID1). Я даже попытался поместить атрибут [InverseProperty] на MasterAccount и SecondMasterAccount, чтобы указать на списки, и это дает мне ошибку каждый раз (EDIT: Это дает мне NullReferenceException).

Я знаю, что я должен превратить его в многие-ко-многим, но я столкнулся срок в ближайшее время, и рефакторинга использования MasterAccount и MasterAccountID бы меня далеко за пределы срока.

Как я могу заставить это работать?

EDIT: Исключение трассировки стека:

System.NullReferenceException was unhandled by user code 
    HResult=-2147467261 
    Message=Object reference not set to an instance of an object. 
    Source=EntityFramework 
    StackTrace: 
     at System.Data.Entity.ModelConfiguration.Configuration.Types.EntityTypeConfiguration.Configure(EdmEntityType entityType, EdmModel model) 
     at System.Data.Entity.ModelConfiguration.Configuration.ModelConfiguration.ConfigureEntities(EdmModel model) 
     at System.Data.Entity.ModelConfiguration.Configuration.ModelConfiguration.Configure(EdmModel model) 
     at System.Data.Entity.DbModelBuilder.Build(DbProviderManifest providerManifest, DbProviderInfo providerInfo) 
     at System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection) 
     at System.Data.Entity.Infrastructure.EdmxWriter.WriteEdmx(DbContext context, XmlWriter writer) 
     at System.Data.Entity.Migrations.Extensions.DbContextExtensions.<>c__DisplayClass1.<GetModel>b__0(XmlWriter w) 
     at System.Data.Entity.Migrations.Extensions.DbContextExtensions.GetModel(Action`1 writeXml) 
     at System.Data.Entity.Migrations.Extensions.DbContextExtensions.GetModel(DbContext context) 
     at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration, DbContext usersContext) 
     at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration) 
     at System.Data.Entity.MigrateDatabaseToLatestVersion`2.InitializeDatabase(TContext context) 
     at System.Data.Entity.Database.<>c__DisplayClass2`1.<SetInitializerInternal>b__0(DbContext c) 
     at System.Data.Entity.Internal.InternalContext.<>c__DisplayClass8.<PerformDatabaseInitialization>b__6() 
     at System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action) 
     at System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization() 
     at System.Data.Entity.Database.Initialize(Boolean force) 
     at Tests.Core.UI.SessionStartTests.ShouldSuccessfullyInitializeDatabase() in c:\Projects\Current\tests\Tests.Core\UI\StartTests.cs:line 72 
    InnerException: 

EDIT 2: Когда я использовал предложение мохо в:

System.Data.Entity.ModelConfiguration.ModelValidationException : One or more validation errors were detected during model generation: 

\tSystem.Data.Entity.Edm.EdmAssociationEnd: : Multiplicity is not valid in Role 'SystemAccount_AllSubAccounts_Target' in relationship 'SystemAccount_AllSubAccounts'. Valid values for multiplicity for the Principal Role are '0..1' or '1'. 
\tSystem.Data.Entity.Edm.EdmAssociationEnd: : Multiplicity is not valid in Role 'SystemAccount_AllSubAccounts_Source' in relationship 'SystemAccount_AllSubAccounts'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'. 
\tSystem.Data.Entity.Edm.EdmAssociationEnd: : Multiplicity is not valid in Role 'SystemAccount_SecondarySubAccounts_Target' in relationship 'SystemAccount_SecondarySubAccounts'. Valid values for multiplicity for the Principal Role are '0..1' or '1'. 
\tSystem.Data.Entity.Edm.EdmAssociationEnd: : Multiplicity is not valid in Role 'SystemAccount_SecondarySubAccounts_Source' in relationship 'SystemAccount_SecondarySubAccounts'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'. 

EDIT 3: Мой код для обновления базы данных:

Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDbContext, Configuration>()); 
var db = new MyDbContext(); 
db.Database.Initialize(true); 

Мой OnModelCreating метод:

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); 

modelBuilder.Entity<ClientStatisticsView>().ToTable("ClientStatistics"); 

base.OnModelCreating(modelBuilder); 

Мой Configuration файл:

public Configuration() 
{ 
    AutomaticMigrationsEnabled = true; 
    AutomaticMigrationDataLossAllowed = true; 
} 

protected override void Seed(MyDbContext context) 
{ 
} 
+0

Я предполагаю, что код происходит от системной учетной записи, вы можете разместить основную учетную запись, то и соотношение между этими двумя – Gustavo

+0

Основная учетная запись поступает из той же таблицы. Это само по себе. – IronMan84

+0

Какова ошибка, возникающая при использовании атрибута '[InverseProperty]'? (Этот атрибут был бы моим предложением решить проблему ...) – Slauma

ответ

1

Мое решение основано на советах, которые я получил от @Slauma и @Moho (+1 к вам обоим за вашу помощь!).

Это правда, что атрибут [InverseProperty] отсутствует, но он не работает, когда я просто помещаю его в файл. Затем, когда я попробовал код @ Moho в совершенно новом файле, он все равно не работал. Поэтому я переключил [ForeignKey] атрибуты от того, на полях ID, чтобы быть на объекте поля сами, т.е .:

public int? PrimaryParentId { get; set; } 
public int? SecondaryParentId { get; set; } 

[ForeignKey("PrimaryParent")] 
public virtual HierarchicalEntity PrimaryParent { get; set; } 

[ForeignKey("SecondaryParent")] 
public virtual HierarchicalEntity SecondaryParent { get; set;} 

Это в конечном итоге работает. Но когда я попытался сделать это на моем классе SystemAccount, это не сработало. Поэтому я сделал следующие шаги, чтобы заставить его работать:

  1. Прокомментировал объекты списка, а также родительские записи и атрибут FK из обоих полей.
  2. Мигрировать базы данных. Все FK теперь сброшены.
  3. незакомментированной его
  4. Проверено, что атрибут [InverseProperty] был на объекты списка, и поставить атрибут [ForeignKey] на virtual объектов.
  5. Мигрировать базы данных. Единственные FK, которые появляются, - это те, которые я хочу быть FK!

Я знаю, что это странное решение, но до тех пор, как он работает ...

+0

Может кто-то, пожалуйста, помогите мне https: // stackoverflow.ком/вопросы/45784482/как к рукоятками-многие-ко-многим-же стол-пользователь-в-Asp-нетто-5 MVC-свободно-апи-# 45784658 – Unbreakable

4

Вы пробовали декорирования свойства коллекции с атрибутом InverseProperty?

[InverseProperty("MasterAccount")] 
public virtual List<SystemAccount> AllSubAccounts { get; set; } 

[InverseProperty("SecondMasterAccount")] 
public virtual List<SystemAccount> SecondarySubAccounts { get; set; } 

Вот демо, который работает для меня:

public class HierarchicalEntity 
{ 
    public int Id { get; set; } 
    public string Description { get; set; } 

    [ForeignKey("PrimaryParent")] 
    public int? PrimaryParentId { get; set; } 

    [ForeignKey("SecondaryParent")] 
    public int? SecondaryParentId { get; set; } 
    public virtual HierarchicalEntity PrimaryParent { get; set; } 

    public virtual HierarchicalEntity SecondaryParent { get; set;} 

    [InverseProperty("PrimaryParent")] 
    public ICollection<HierarchicalEntity> ChildrenViaPrimaryParent { get; set; } 

    [InverseProperty("SecondaryParent")] 
    public ICollection<HierarchicalEntity> ChildrenViaSecondaryParent { get; set; } 
} 

multiple self-references

+0

У меня другая ошибка. См. Править. – IronMan84

+0

Есть ли у вас какая-то текущая конфигурация api, которую вы не показывали? – Moho

+0

Нет. Только это: 'modelBuilder.Conventions.Remove ();' – IronMan84

3

Я воспроизвели проблему с помощью EF 5. Я получаю точно такое же исключение и трассировки стека, а также исключение в вашем EDIT 2 при применении кода Мохо. Проблема не возникает с EF 6. Итак, если обновление до EF 6 - это вариант для вас, который бы разрешил проблему.

Если вам нужно придерживаться EF 5 с использованием сопоставления API Fluent вместо использования атрибута [InverseProperty], который работал для меня без исключений.Вы можете удалить все атрибуты, то: отображение

public class SystemAccount 
{ 
    public int ID { get; set; } 

    public int? MasterAccountID { get; set; } 
    public int? SecondMasterAccountID { get; set; } 

    public virtual SystemAccount MasterAccount { get; set; } 
    public virtual SystemAccount SecondMasterAccount { get; set; } 

    public virtual List<SystemAccount> AllSubAccounts { get; set; } 
    public virtual List<SystemAccount> SecondarySubAccounts { get; set; } 
} 

Отношения с Fluent API:

modelBuilder.Entity<SystemAccount>() 
    .HasOptional(s => s.MasterAccount) 
    .WithMany(s => s.AllSubAccounts) 
    .HasForeignKey(s => s.MasterAccountID); 

modelBuilder.Entity<SystemAccount>() 
    .HasOptional(s => s.SecondMasterAccount) 
    .WithMany(s => s.SecondarySubAccounts) 
    .HasForeignKey(s => s.SecondMasterAccountID); 

появляется Тот факт, что атрибут [InverseProperty] вашей модели вызывает исключения быть ошибка в EF 5. ошибка является скорее всего, связано с самореферентным видом отношений, потому что обычно с отношениями между разными сущностями атрибут работает без проблем.

Смежные вопросы