我在 VS2012 中使用 MVC4,并且我正在遵循一个 table-per-type 继承方法。我正在尝试使用该Seed()
方法将数据添加到我的数据库中。
我有以下课程:
房东
[Table("Landlord")]
public class Landlord : UserProfile
{
// A Landlord can have many ResidentialProperties
[ForeignKey("ResidentialPropertyId")]
public virtual ICollection<ResidentialProperty> ResidentialProperties { get; set; }
}
住宅物业
[Table("ResidentialProperty")]
public class ResidentialProperty
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ResidentialPropertyId { get; set; }
// A ResidentialProperty has 1 Landlord
public virtual int UserId { get; set; }
public virtual UserProfile UserProfile { get; set; }
}
所以Landlord
继承自UserProfile
,因此没有 PK 属性Landlord.
我试图实现的关系如下:
- A
Landlord
可以有很多ResidentialProperties
(1:n) - 一个
ResidentialProperty
罐子(在应用程序的范围内)有一个Landlord
(1:1)
我认为我配置模型的方式足以update-database
成功地从包管理器运行命令,并将我的Seed()
方法中的内容添加到我的数据库中。事实并非如此,我收到以下错误:
无法确定“LetLord.Models.ResidentialProperty_UserProfile”关系的主体端。多个添加的实体可能具有相同的主键。
在阅读之后,我意识到我想要创建的关系需要使用 Fluent API 来实现,所以我尝试了以下方法:
modelBuilder.Entity<Landlord>()
.HasMany(x => x.ResidentialProperties)
.WithOptional()
.HasForeignKey(x => x.ResidentialPropertyId);
modelBuilder.Entity<ResidentialProperty>()
.HasRequired(x => x.UserProfile);
当我尝试update-database
通过包管理器执行命令时,出现以下错误:
\tSystem.Data.Entity.Edm.EdmAssociationEnd: : 多重性在关系“Landlord_ResidentialProperties”中的角色“Landlord_ResidentialProperties_Target”中无效。因为从属角色指的是关键属性,所以从属角色的多重性的上限必须是“1”。
我完全不知道如何解决我的问题。我在这上面花了很多时间,这非常令人沮丧,因为我觉得它应该很容易完成。如果有人有解决方案,如果您能与我分享,我将不胜感激。
编辑- 上述第一个错误引发的异常输出:
System.Data.Entity.Infrastructure.DbUpdateException:无法确定“LetLord.Models.ResidentialProperty_Landlord”关系的主体端。多个添加的实体可能具有相同的主键。---> System.Data.UpdateException:无法确定“LetLord.Models.ResidentialProperty_Landlord”关系的主体端。多个添加的实体可能具有相同的主键。在 System.Data.Mapping.Update.Internal.UpdateTranslator.RegisterEntityReferentialConstraints(IEntityStateEntry stateEntry, Boolean currentValues) 在 System.Data.Mapping.Update.Internal.UpdateTranslator.RegisterReferentialConstraints(IEntityStateEntry stateEntry) 在 System.Data.Mapping.Update.Internal。 UpdateTranslator.PullModifiedEntriesFromStateManager() 在 System.Data.Mapping.Update.Internal.UpdateTranslator。
编辑- 解决方案:
实体应该按照下面拉迪斯拉夫的回答,我的错误是在基类的多方面而不是派生类上创建导航属性。
Seed()
我的下一个错误是在我的方法中对实体进行排序。我在下面添加了它们应该是什么样的,这尤其适用于添加具有关联的实体时。
protected override void Seed(LetLord.Models.LetLordContext context)
{
try
{
#region Landlords
// create a list of landlords first - a landlord can have many residential properties, make this = new List<ResidentialProperty>()
var landlords = new List<Landlord>
{
// landlord 1
new Landlord { UserName="Frank", FirstName="Frank", LastName="O'Sullivan", Email="a@a.com", AccountType=(int)AccountType.Landlord, ResidentialProperties = new List<ResidentialProperty>() }
// ...
};
landlords.ForEach(l => context.UserProfile.AddOrUpdate(l));
context.SaveChanges();
#endregion
#region ResidentialProperties
// then create a list of properties
var residentialProperties = new List<ResidentialProperty>
{
// Property 1 associated with LandLord 1
new ResidentialProperty { PropTypeValue=(int)PropertyType.Detached, Description="Some description...", NumberOfBedrooms="4", NumberOfReceptionRooms="2", NumberOfBathrooms="2", HasBackGarden=true, HasFrontGarden=true, HasSecureParking=false, IsDisabledFriendly=false, DateAdded=DateTime.Now, Landlord = landlords.FirstOrDefault(u => u.UserId == 11) } // in my case, user 11 is landlord 1
// ...
};
residentialProperties.ForEach(rp => context.ResidentialProperty.AddOrUpdate(rp));
context.SaveChanges();
#endregion
// then add our list of properties to our list of landlords
landlords[0].ResidentialProperties.Add(residentialProperties[0]);
landlords[1].ResidentialProperties.Add(residentialProperties[1]);
landlords[2].ResidentialProperties.Add(residentialProperties[2]);
landlords[3].ResidentialProperties.Add(residentialProperties[3]);
landlords[4].ResidentialProperties.Add(residentialProperties[4]);
landlords[5].ResidentialProperties.Add(residentialProperties[5]);
landlords[6].ResidentialProperties.Add(residentialProperties[6]);
landlords[7].ResidentialProperties.Add(residentialProperties[7]);
landlords[8].ResidentialProperties.Add(residentialProperties[8]);
landlords[9].ResidentialProperties.Add(residentialProperties[9]);
context.SaveChanges();
}
catch (Exception ex)
{
string lines = ex.ToString();
System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\Users\Home\Desktop\error.txt");
file.WriteLine(lines);
file.Close();
}
当我在修复上述代码后尝试运行时update-database
,遇到了这个错误:
System.Data.Entity.Infrastructure.DbUpdateException:更新条目时出错。有关详细信息,请参阅内部异常。---> System.Data.UpdateException:更新条目时出错。有关详细信息,请参阅内部异常。---> System.Data.SqlClient.SqlException:INSERT 语句与 FOREIGN KEY 约束“FK_dbo.ResidentialProperty_dbo.Landlord_UserId”冲突。冲突发生在数据库“C:\USERS\HOME\DESKTOP\LETLORD\LETLORD\APP_DATA\LETLORD.MDF”、表“dbo.Landlord”、列“UserId”中。该语句已终止。
经过快速搜索后,我发现(我认为)导致了这个错误,因为我的数据库中已经有数据。删除并重新创建数据库解决了这个问题,当我Seed()
再次运行该方法时,数据已成功添加。