实体框架“发生关系多重性约束违规”

时间:2017-03-24 13:22:53

标签: c# entity-framework ef-migrations

我今天早上从实体框架收到了这个错误:

发生了关系多重性约束违规: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();
    }
}

但是在收到错误后我试图在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”。

我的数据库似乎有些明显错误,但我看不出是什么以及为什么。

2 个答案:

答案 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实际上包含地址列表。