Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为一对一关系配置的EF 6有时会违反约束_C#_Sql Server_Entity Framework_Entity Framework 6 - Fatal编程技术网

C# 为一对一关系配置的EF 6有时会违反约束

C# 为一对一关系配置的EF 6有时会违反约束,c#,sql-server,entity-framework,entity-framework-6,C#,Sql Server,Entity Framework,Entity Framework 6,我正在使用EF 6.1.3中的Fluent API定义实体用户和实体电子商务艺术之间的一对一关系。在99.9%的时间里,一切似乎都很正常,但偶尔我们的异常记录器会告诉我们,在尝试访问User.Cart时,会引发以下异常: 发生关系多重性约束冲突:EntityReference不能有多个相关对象,但查询返回多个相关对象。 我们检查了数据库,似乎Entity Framework为同一用户创建了两个Cart,尽管实体类型之间存在一对一的关系 最让我印象深刻的是,当创建实体时不会发生异常,而是当代码试图

我正在使用EF 6.1.3中的Fluent API定义实体
用户
和实体
电子商务艺术
之间的一对一关系。在99.9%的时间里,一切似乎都很正常,但偶尔我们的异常记录器会告诉我们,在尝试访问
User.Cart
时,会引发以下异常:

发生关系多重性约束冲突:EntityReference不能有多个相关对象,但查询返回多个相关对象。

我们检查了数据库,似乎Entity Framework为同一用户创建了两个Cart,尽管实体类型之间存在一对一的关系

最让我印象深刻的是,当创建实体时不会发生异常,而是当代码试图访问
User.Cart
,在数据库中找到多个结果时才会发生异常

你知道这是怎么发生的吗

PS:我正在使用延迟加载,尽管我不认为这会有什么不同

这些是我的实体: 以下是我的配置文件:
公共类用户配置:EntityTypeConfiguration
{
公共用户配置()
{
HasKey(x=>x.Id);
属性(x=>x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired();
hasportional(x=>x.Cart).WithOptionalPrincipal(y=>y.User).Map(x=>x.MapKey(“用户Id”);
}
}
公共类电子商务合作伙伴配置:EntityTypeConfiguration
{
公共电子商务合作伙伴配置()
{
HasKey(a=>a.Id);
属性(a=>a.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired();
}
}
这就是电子商务艺术表格的样子:

根据建议,我创建了以下迁移,强制 外键
用户Id
是唯一的:

public partial class EcommerceCart_User_Index : DbMigration
{
    public override void Up()
    {
        DropIndex("dbo.EcommerceCarts", new[] { "User_Id" });
        Sql(
            @"CREATE UNIQUE NONCLUSTERED INDEX IX_User_Id
            ON dbo.EcommerceCarts(User_Id)
            WHERE User_Id IS NOT NULL");
    }
}
不幸的是,我找不到任何其他使用fluentapi的解决方案,因为如果不使用SQL,似乎无法在导航属性上创建唯一的索引


如果有人知道更好的解决方案,请告诉我。

即使不使用EF,如果用户主键也是购物车的主键(一对一关系就是这样),并且主键是唯一的,那么您的数据库怎么可能为一个用户拥有多个购物车?您的EF配置错误,或者您错过了部署迁移。如果我查看数据库,那么用户主键也不是购物车的主键。EcommerceCarts表具有用户Id外键。我认为这很正常?所以我要么将Cart.UserId设置为外键和主键,要么如果您想保持原样,至少在其上添加一个唯一的约束以保持数据的完整性。这是一篇关于如何设置它的好文章。这是有道理的,但我不知道怎么做。您链接的教程解释了我已经做了什么,但没有提到如何向外键添加唯一约束。我试图添加
属性(x=>x.User.Id).HasColumnAnnotation(IndexAnnotation.AnnotationName,newindexAnnotation(newindexAttribute{IsUnique=true}))
到EcommerceCartConfiguration文件,但当我尝试生成迁移时,我得到错误“类型‘User’已配置为实体类型。无法将其重新配置为复杂类型”。上面显示的fluent API配置代码是多余的。EF可以仅从您的模型推断出所有这些。我将首先删除所有配置,看看这是否解决了问题。尽管从您描述错误的方式中我有一个线索,您的问题不在模型或fluent API配置中,而是在向数据库添加或更新
ecommerceart
对象的业务逻辑中。这个错误听起来像是你在调用
.Single()
.SingleOrDefault()
我会把它放在一个try catch中,以帮助找出添加了多个购物车的位置。在
Up
方法中,可以使用
CreateIndex
而不是
Sql
。但要点是适用的——它必须在迁移中完成。不存在fluent API。一般来说,一对一FK关系支持非常有限(与“标准”共享PK模型相反)。@IvanStoev与
CreateIndex
相比,我似乎不能像在Sql语句
中那样允许空字段,其中用户Id不为空
public class UserConfiguration : EntityTypeConfiguration<User>
{
    public UserConfiguration()
    {
        HasKey(x => x.Id);
        Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired();
        HasOptional(x => x.Cart).WithOptionalPrincipal(y => y.User).Map(x => x.MapKey("User_Id"));
    }
}

public class EcommerceCartConfiguration : EntityTypeConfiguration<EcommerceCart>
{
    public EcommerceCartConfiguration()
    {
        HasKey(a => a.Id);
        Property(a => a.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired();
    }
}
public partial class EcommerceCart_User_Index : DbMigration
{
    public override void Up()
    {
        DropIndex("dbo.EcommerceCarts", new[] { "User_Id" });
        Sql(
            @"CREATE UNIQUE NONCLUSTERED INDEX IX_User_Id
            ON dbo.EcommerceCarts(User_Id)
            WHERE User_Id IS NOT NULL");
    }
}