两个在同一个表1对多的关系 [英] Two One-to-Many relationships in the same table

查看:354
本文介绍了两个在同一个表1对多的关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为表 SystemAccount ,它(直到最近)有一个 MasterAccountID 就可以将点其父账户(显然是 INT?)。我的客户已经告诉我,有可能是在那里,有时一个账户可以有2母账户(无曾经有不止于此)。我一直试图让我在 SystemAccount 类的调整,但它没有产生我想要的关系。



下面是类代码部分:

  [ForeignKey的(MasterAccount)] 
公众诠释? MasterAccountID {搞定;组; }

[ForeignKey的(SecondMasterAccount)]
公众诠释? SecondMasterAccountID {搞定;组; }

公共虚拟SystemAccount MasterAccount {搞定;组; }

公共虚拟SystemAccount SecondMasterAccount {搞定;组; }

公共虚拟目录< SystemAccount> AllSubAccounts {搞定;组; }

公共虚拟目录< SystemAccount> SecondarySubAccounts {搞定;组; }

当我这样做,我得到4 FKS表中,其中2个是自动生成的( SystemAccount_ID SystemAccount_ID1 )。我甚至试过把 [InverseProperty] 属性的 MasterAccount SecondMasterAccount 指向列表,而且每次给我一个错误(编辑:它给了我一个的NullReferenceException



我知道,我的的使之成为一个多一对多的关系,但我很快就面临着一个期限,并重构的用途MasterAccount MasterAccountID 会带我远远超出最后期限。



我怎样才能得到?这个工作。



编辑:异常堆栈跟踪:

 系统.NullReferenceException是由用户代码
HResult的= -2147467261
消息=对象引用未设置到对象的实例未处理。
来源=的EntityFramework
堆栈跟踪:
在System.Data.Entity.ModelConfiguration.Configuration.Types.EntityTypeConfiguration.Configure(EdmEntityType的EntityType,EdmModel模型)
在System.Data.Entity的.ModelConfiguration.Configuration.ModelConfiguration.ConfigureEntities(EdmModel模型)
在System.Data.Entity.ModelConfiguration.Configuration.ModelConfiguration.Configure(EdmModel模型)
在System.Data.Entity.DbModelBuilder.Build(DbProviderManifest providerManifest,DbProviderInfo providerInfo)
在System.Data.Entity.DbModelBuilder.Build(的DbConnection providerConnection)
在System.Data.Entity.Infrastructure.EdmxWriter.WriteEdmx(的DbContext背景下,作家的XmlWriter)
在System.Data.Entity.Migrations.Extensions.DbContextExtensions&下;方式> c__DisplayClass1&所述; GetModel> b__0(的XmlWriter w)的
。在System.Data.Entity.Migrations.Extensions.DbContextExtensions.GetModel(Action`1中WriteXML)
在System.Data.Entity.Migrations.Extensions.DbContextExtensions.GetModel(的DbContext上下文)
在System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration配置的DbContext usersContext)
在System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration配置)
在System.Data.Entity.MigrateDatabaseToLatestVersion`2.InitializeDatabase(TContext上下文)
在System.Data.Entity的。 。数据库<> c__DisplayClass2`1< SetInitializerInternal方式> b__0(的DbContext C)
在System.Data.Entity.Internal.InternalContext<> c__DisplayClass8< PerformDatabaseInitialization> b__6()
。在System.Data.Entity.Internal.InternalContext.PerformInitializationAction(动作动作)在System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization
()
在System.Data.Entity.Database.Initialize(布尔力)
在Tests.Core.UI.SessionStartTests.ShouldSuccessfullyInitializeDatabase(c)中:\Projects\Current\tests\Tests.Core\UI\StartTests.cs:行72
的InnerException:

编辑2:当我用莫霍面的建议:

  System.Data.Entity.ModelConfiguration.ModelValidationException:模型生成过程中检测到一个或多个验证错误:

\tSystem.Data。 Entity.Edm.EdmAssociationEnd:多重不是在关系'SystemAccount_AllSubAccounts角色SystemAccount_AllSubAccounts_Target有效。对于多样性的主体作用,有效值为0..1'或'1'。
\tSystem.Data.Entity.Edm.EdmAssociationEnd:多重不是在关系'SystemAccount_AllSubAccounts角色SystemAccount_AllSubAccounts_Source有效。因为从属角色属性不是关键性质,上限的从属地位的多重性必须是'*'。
\tSystem.Data.Entity.Edm.EdmAssociationEnd:多重不是在关系'SystemAccount_SecondarySubAccounts角色SystemAccount_SecondarySubAccounts_Target有效。对于多样性的主体作用,有效值为0..1'或'1'。
\tSystem.Data.Entity.Edm.EdmAssociationEnd:多重不是在关系'SystemAccount_SecondarySubAccounts角色SystemAccount_SecondarySubAccounts_Source有效。因为从属角色属性不是关键性质,上限的从属地位的多重性必须是'*'。



编辑3:我对更新数据库的代码:

  Database.SetInitializer(新MigrateDatabaseToLatestVersion< MyDbContext,结构>()); 
变种DB =新MyDbContext();
db.Database.Initialize(真);



我的 OnModelCreating 方法:



  modelBuilder.Conventions.Remove< OneToManyCascadeDeleteConvention>(); 

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

base.OnModelCreating(模型构建器);



我的配置文件:

 公共配置()
{
AutomaticMigrationsEnabled = TRUE;
AutomaticMigrationDataLossAllowed = TRUE;
}

保护覆盖无效种子(MyDbContext上下文)
{
}


解决方案

我的解决方案是基于我从@Slauma和@Moho了(+1双方你的帮助!)的意见。



这是事实,在 [InverseProperty] 属性是什么失踪,但我只是把它不会工作它上的文件。然后,当我在一个完全新的文件试图@莫霍面的代码,它仍然没有奏效。所以,我切换了 [ForeignKey的] 属性被上的ID字段是在目标域自身,即:

 公众诠释? PrimaryParentId {搞定;组; } 
公众诠释? SecondaryParentId {搞定;组; }

[ForeignKey的(PrimaryParent)]
公共虚拟HierarchicalEntity PrimaryParent {搞定;组; }

[ForeignKey的(SecondaryParent)]
公共虚拟HierarchicalEntity SecondaryParent {搞定;设置;}

这结束了工作。但是,当我试图这样做,我的 SystemAccount 类这是行不通的。所以,我最后做以下步骤来得到它的工作:




  1. 注释掉列表对象,以及父记录,和来自这两个领域的FK属性。

  2. 迁移的数据库。所有FKS现在已经下降。

  3. 取消注释出来

  4. 检查发现 [InverseProperty] 属性是在列表对象,并把 [ForeignKey的] 属性上的虚拟的对象。

  5. 迁移的数据库。这显示只有FKS是我想是FKS的那些!



我知道这是一个奇怪的解决方案,但只要因为它的工作原理...


I have a table called SystemAccount, which (up until recently) had a MasterAccountID on it that would point to its parent account (obviously an int?). My client has now told me that there may be sometimes where an account can have 2 parent accounts (none ever have more than that). I've been trying to make the adjustment in my SystemAccount class, but it's not generating the relationship that I want.

Here's part of the class code:

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

When I do this I get 4 FKs in the table, 2 of which are auto-generated (SystemAccount_ID and SystemAccount_ID1). I've even tried to put the [InverseProperty] attribute on MasterAccount and SecondMasterAccount to point to the Lists, and it gives me an error each time (EDIT: It gives me a NullReferenceException).

I know that I should make it into a many-to-many relationship, but I'm facing a deadline soon, and refactoring the uses of MasterAccount and MasterAccountID would take me way beyond the deadline.

How can I get this to work?

EDIT: Exception stack trace:

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: When I used Moho's suggestion:

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: My code for updating the database:

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

My OnModelCreating method:

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

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

base.OnModelCreating(modelBuilder);

My Configuration file:

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

protected override void Seed(MyDbContext context)
{
}

解决方案

My solution is based on the advice I got from @Slauma and @Moho (+1 to both of you for your help!).

It is true that the [InverseProperty] attribute is what was missing, but it wouldn't work when I just put it on the file. Then, when I tried @Moho's code in a completely new file, it still didn't work. So I switched the [ForeignKey] attributes from being on the ID fields to being on the object fields themselves, i.e.:

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

That ended up working. But when I tried doing that on my SystemAccount class it wouldn't work. So I ended up doing the following steps to get it to work:

  1. Commented out the list objects, as well as the parent records, and the FK attribute from both fields.
  2. Migrated the database. All FKs now dropped.
  3. Uncommented it out
  4. Checked that the [InverseProperty] attribute was on the list objects, and put the [ForeignKey] attribute on the virtual objects.
  5. Migrated the database. The only FKs that show up are the ones that I want to be FKs!

I know that it's a weird solution, but as long as it works...

这篇关于两个在同一个表1对多的关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆