两个在同一个表1对多的关系 [英] Two One-to-Many relationships in the same table
问题描述
我有一个名为表 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
类这是行不通的。所以,我最后做以下步骤来得到它的工作:
- 注释掉列表对象,以及父记录,和来自这两个领域的FK属性。
- 迁移的数据库。所有FKS现在已经下降。
- 取消注释出来
- 检查发现
[InverseProperty]
属性是在列表对象,并把[ForeignKey的]
属性上的虚拟
的对象。 - 迁移的数据库。这显示只有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:
- Commented out the list objects, as well as the parent records, and the FK attribute from both fields.
- Migrated the database. All FKs now dropped.
- Uncommented it out
- Checked that the
[InverseProperty]
attribute was on the list objects, and put the[ForeignKey]
attribute on thevirtual
objects. - 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屋!