问题
I received this error from Entity Framework this morning:
A relationship multiplicity constraint violation occurred: An EntityReference can have no more than one related object, but the query returned more than one related object. This is a non-recoverable error.
The error refers to a very simple One-To-Many relationship between User
and 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; }
}
I'm using Fluent API to configure the relationship between entities, but in this case the relationship seems to simple that at first I didn't specify any particular rule and I let EF "deduce" the relationship:
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();
}
}
But after receiving the error I tried to specify the following rule in the 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
}
}
After doing that, I tried generating a new automatic migration, and this is what I obtained:
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");
}
}
I found this very odd. The Db seemed ok even before, with the Addresses Table having a Foreign Key "User_Id", but after specifying the one-to-many relationship in the Configuration file EF wants to create a different Foreign Key. Why??
I also tried to specify HasOptional(x => x.User).WithMany().Map(x => x.MapKey("User_Id"));
, but in that case when I try to create the automatic migration I receive the following error:
User_Id: Name: Each property name in a type must be unique. Property name 'User_Id' is already defined.
It seems like something is clearly wrong with my DB, but I can't see what and why.
回答1:
There are other techniques, but I prefer to put the FK in explicitly:
public class Address
{
public Guid Id { get; set; }
public Int? User_Id { get; set; }
public User User { get; set; }
}
Then use this fluent code:
HasOptional(x => x.User).WithMany(x => x.Addresses).HasForeignKey(x => x.User_Id);
回答2:
I realized that I needed to change my Configuration file as it follows:
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()
(without parameter) is for when there is no navigation property on the other side of the relationship, while in this case I needed to spacify .WithMany(x => x.Addresses)
because User
actually contains a list of Addresses.
来源:https://stackoverflow.com/questions/43000646/entity-framework-a-relationship-multiplicity-constraint-violation-occurred