Entity Framework "A relationship multiplicity constraint violation occurred"
Entity Framework "A relationship multiplicity constraint violation occurred"
今天早上我从 Entity Framework 收到了这个错误:
发生了关系多重性约束冲突:一个 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 "deduce" 关系:
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 之前似乎还不错,地址 Table 有一个外键 "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()
(不带参数)适用于关系的另一侧没有导航 属性 的情况,而在这种情况下,我需要 spacify .WithMany(x => x.Addresses)
因为 User
实际上包含一个地址列表。
今天早上我从 Entity Framework 收到了这个错误:
发生了关系多重性约束冲突:一个 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 "deduce" 关系:
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 之前似乎还不错,地址 Table 有一个外键 "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()
(不带参数)适用于关系的另一侧没有导航 属性 的情况,而在这种情况下,我需要 spacify .WithMany(x => x.Addresses)
因为 User
实际上包含一个地址列表。