实体框架"A relationship multiplicity constraint violation occurred"



我今天早上从实体框架收到此错误:

发生关系多重性约束冲突:EntityReference 只能有一个相关对象,但查询返回多个相关对象。这是一个不可恢复的错误。

该错误是指UserAddress之间非常简单的一对多关系

public class User
{
public Guid Id { get; set; }
public virtual IList<Address> Addresses { get; set; }
} 
public class Address
{
public Guid Id { get; set; }
public User User { get; set; }
} 

我正在使用 Fluent API 来配置实体之间的关系,但在这种情况下,关系似乎很简单,起初我没有指定任何特定规则,我让 EF "推断"关系:

public class AddressConfiguration : EntityTypeConfiguration<Address>
{
public AddressConfiguration()
{
HasKey(a => a.Id);
Property(a => a.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired();
}
}
public class UserConfiguration : EntityTypeConfiguration<User>
{
public UserConfiguration()
{
HasKey(u => u.Id);
Property(u => u.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired();
}
}

但是在收到错误后,我尝试在地址配置中指定以下规则:

public class AddressConfiguration : EntityTypeConfiguration<Address>
{
public AddressConfiguration()
{
HasKey(a => a.Id);
Property(a => a.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired();
HasOptional(x => x.User).WithMany(); // I tried adding this
}
}

完成此操作后,我尝试生成新的自动迁移,这就是我获得的:

public partial class AddressFixMigration : DbMigration
{
public override void Up()
{
DropForeignKey("dbo.Addresses", "User_Id", "dbo.Users");
AddColumn("dbo.Addresses", "User_Id1", c => c.Guid());
CreateIndex("dbo.Addresses", "User_Id1");
AddForeignKey("dbo.Addresses", "User_Id1", "dbo.Users", "Id");
}
public override void Down()
{
DropForeignKey("dbo.Addresses", "User_Id1", "dbo.Users");
DropIndex("dbo.Addresses", new[] { "User_Id1" });
DropColumn("dbo.Addresses", "User_Id1");
AddForeignKey("dbo.Addresses", "User_Id", "dbo.Users", "Id");
}
}

我觉得这很奇怪。Db之前似乎还可以,地址表具有外键"User_Id",但是在配置文件中指定一对多关系后,EF想要创建一个不同的外键。为什么??

我还尝试指定HasOptional(x => x.User).WithMany().Map(x => x.MapKey("User_Id"));,但是在这种情况下,当我尝试创建自动迁移时,我收到以下错误:

User_Id:名称:类型中的每个属性名称必须是唯一的。属性名称"User_Id"已定义。

我的数据库似乎明显出了问题,但我看不出是什么以及为什么。

还有其他技术,但我更喜欢明确地将 FK 放入:

public class Address
{
public Guid Id { get; set; }
public Int? User_Id { get; set; }
public User User { get; set; }
} 

然后使用以畅的代码:

HasOptional(x => x.User).WithMany(x => x.Addresses).HasForeignKey(x => x.User_Id);

我意识到我需要更改我的配置文件,如下所示:

public class AddressConfiguration : EntityTypeConfiguration<Address>
{
public AddressConfiguration()
{
HasKey(a => a.Id);
Property(a => a.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired();
HasOptional(x => x.User).WithMany(x => x.Addresses).Map(x => x.MapKey("User_Id"));
}
}

.WithMany()(无参数)适用于关系另一端没有导航属性的情况,而在这种情况下,我需要分隔.WithMany(x => x.Addresses)User因为它实际上包含一个地址列表。

相关内容

最新更新