我今天早上从实体框架收到了这个错误:
发生了关系多重性约束违规:EntityReference只能有一个相关对象,但查询返回了多个相关对象。这是一个不可恢复的错误。
错误是指User
和Address
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();
}
}
但是在收到错误后我试图在AddressConfiguration中指定以下规则:
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”。
我的数据库似乎有些明显错误,但我看不出是什么以及为什么。
答案 0 :(得分:0)
还有其他技术,但我更愿意明确地使用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);
答案 1 :(得分:0)
我意识到我需要更改配置文件,如下所示:
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
实际上包含地址列表。