Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.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# 无法更改关系,因为保存时一个或多个外键属性不可为null_C#_Entity Framework_Entity Framework 6_Graphdiff - Fatal编程技术网

C# 无法更改关系,因为保存时一个或多个外键属性不可为null

C# 无法更改关系,因为保存时一个或多个外键属性不可为null,c#,entity-framework,entity-framework-6,graphdiff,C#,Entity Framework,Entity Framework 6,Graphdiff,我使用更新分离的对象图,在保存父对象及其子对象时,会出现上述异常 模型和映射为: public class Group { public int Id { get; set; } public virtual ICollection<GroupUser> Users{ get; set; } } public class GroupUser { public int Id { get; set; } public int GroupId { get;

我使用更新分离的对象图,在保存父对象及其子对象时,会出现上述异常

模型和映射为:

public class Group
{
    public int Id { get; set; }
    public virtual ICollection<GroupUser> Users{ get; set; }
}

public class GroupUser
{
    public int Id { get; set; }
    public int GroupId { get; set; }
    public int UserId { get; set; }
    public virtual User User { get; set; }
}

public class GroupMap : EntityTypeConfiguration<Group>
{
    public GroupMap()
    {
        this.ToTable("groups");
        this.HasKey(t => t.Id).Property(t => t.Id).HasColumnName("id").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        this.HasMany(t => t.Users)
            .WithOptional()
            .HasForeignKey(d => d.GroupId)
            .WillCascadeOnDelete();
    }
}

public class GroupUserMap : EntityTypeConfiguration<GroupUser>
{
    public GroupUserMap ()
    {
        this.ToTable("groups_users");
        this.HasKey(t => t.Id).Property(t => t.Id).HasColumnName("id").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        this.Property(t => t.GroupId).HasColumnName("group_id").IsRequired();
        this.Property(t => t.UserId).HasColumnName("user_id").IsRequired();

        this.HasRequired(t => t.User)
            .WithMany()
            .HasForeignKey(d => d.UserId)
            .WillCascadeOnDelete(false);
    }
}
公共类组
{
公共int Id{get;set;}
公共虚拟ICollection用户{get;set;}
}
公共类GroupUser
{
公共int Id{get;set;}
public int GroupId{get;set;}
public int UserId{get;set;}
公共虚拟用户用户{get;set;}
}
公共类GroupMap:EntityTypeConfiguration
{
公共组映射()
{
本表为ToTable(“组”);
this.HasKey(t=>t.Id).Property(t=>t.Id).HasColumnName(“Id”).hasDatabaseGenerateOption(DatabaseGenerateOption.Identity);
this.HasMany(t=>t.Users)
.WithOptional()
.HasForeignKey(d=>d.GroupId)
.WillCascadeOnDelete();
}
}
公共类GroupUserMap:EntityTypeConfiguration
{
公共GroupUserMap()
{
本表为ToTable(“用户组”);
this.HasKey(t=>t.Id).Property(t=>t.Id).HasColumnName(“Id”).hasDatabaseGenerateOption(DatabaseGenerateOption.Identity);
this.Property(t=>t.GroupId).HasColumnName(“group_id”).IsRequired();
this.Property(t=>t.UserId).HasColumnName(“user_id”).IsRequired();
this.HasRequired(t=>t.User)
.有很多
.HasForeignKey(d=>d.UserId)
.WillCascadeOnDelete(假);
}
}
对于插入和更新,我的存储库中有以下方法:

public override Group Update(Group entity)
{
    if (entity.Users != null)
    {
        entity.Users.ToList()
                    .ForEach(x =>
                    {
                        x.GroupId = x.Id == 0 ? 0 : entity.Id;
                        x.UserId = x.User.Id;
                    });
    }

    return dbContext.UpdateGraph<Group>
        (entity,
            map => map.OwnedCollection(x => x.Users, with => with.AssociatedEntity(c => c.Users))
        );
}
公共覆盖组更新(组实体)
{
if(entity.Users!=null)
{
entity.Users.ToList()
.ForEach(x=>
{
x、 GroupId=x.Id==0?0:entity.Id;
x、 UserId=x.User.Id;
});
}
返回dbContext.UpdateGraph
(b)实体,
map=>map.OwnedCollection(x=>x.Users,with=>with.AssociatedEntity(c=>c.Users))
);
}
我做了以下工作:

  • 添加新组,保存并重新加载
  • 将用户添加到组中,保存并重新加载
  • 添加第二个用户,保存并重新加载
  • 添加第三个用户,尝试保存->引发异常
  • 调试时,添加的用户实体的状态总是分离的,对于新实体,
    GroupId
    Id
    都设置为0。已成功保存前2个添加的用户。但是,在第三个实例中,会抛出异常

    如果我总是使用相同的方法来保存,为什么它不总是有效?这是一个
    EF
    还是
    GraphDiff
    问题,有没有办法解决这个问题


    这里和其他地方的大多数问题和相关答案都涉及删除子实体的情况。在我的特定场景中,情况并非如此。

    您是否尝试查看实体状态在未被EF跟踪时是否正在被修改

    试一试


    ToList()函数也可能导致您意外修改用户状态。

    请尝试此操作。但它未经测试

    public override Group Update(Group entity)
    {
        if (entity.Users != null)
        {
            foreach(var user in entity.Users){
              user.GroupId = x.Id == 0 ? 0 : entity.Id;
              user.UserId = x.User.Id;
             dbContext.Entry(child).State = EntityState.Modified;
            }
    
        }
    
        return dbContext.UpdateGraph<Group>
            (entity,
                map => map.OwnedCollection(x => x.Users, with => with.AssociatedEntity(c => c.Users))
            );
    }
    
    公共覆盖组更新(组实体)
    {
    if(entity.Users!=null)
    {
    foreach(entity.Users中的var用户){
    user.GroupId=x.Id==0?0:entity.Id;
    user.UserId=x.user.Id;
    dbContext.Entry(child.State=EntityState.Modified;
    }
    }
    返回dbContext.UpdateGraph
    (b)实体,
    map=>map.OwnedCollection(x=>x.Users,with=>with.AssociatedEntity(c=>c.Users))
    );
    }
    
    可能与UserId不可为null有关。如您所知,用户ID由EF用于编写用户。如果用户为null(可以),则EF无法写入实体。 它还可能与EF用于映射Group.Users集合的User.GroupId相关

    还有,我不明白你的模型。 一个用户只有一个组。 一个组可以有多个用户

    如果这是真的,为什么不简化模型并删除关联实体呢?EF不需要它

    public class Group
    {
        public int Id { get; set; }
        public virtual ICollection<User> Users{ get; set; }
    }
    
    public class User
    {
        public int Id { get; set; }
        public virtual Group Group { get; set; }
    }
    
    公共类组
    {
    公共int Id{get;set;}
    公共虚拟ICollection用户{get;set;}
    }
    公共类用户
    {
    公共int Id{get;set;}
    公共虚拟组{get;set;}
    }
    
    在这种情况下,您只需要UserMap

    public class UserMap : EntityTypeConfiguration<User>
    {
        public UserMap()
        {
            // You don't need to set primary key. EF take Id and create an identity column
            //HasKey(t => t.Id); 
    
            // Table & Column Mappings
            ToTable("users");
            // No column mappings in this case.
    
            // Relationships
            HasRequired(t => t.Group)
                .WithMany(t => t.Users)
                .Map(d => d.MapKey("user_group"));
    
        }
    }
    
    公共类用户映射:EntityTypeConfiguration
    {
    公共用户映射()
    {
    //您不需要设置主键.EF获取Id并创建标识列
    //HasKey(t=>t.Id);
    //表和列映射
    ToTable(“用户”);
    //在这种情况下没有列映射。
    //关系
    HasRequired(t=>t.Group)
    .WithMany(t=>t.Users)
    .Map(d=>d.MapKey(“用户组”);
    }
    }
    
    如果一个用户可以有多个组,您可以用这种方式修改您的用户模型

    public class User
    {
        public int Id { get; set; }
        public virtual ICollection<Group> Groups { get; set; }
    }
    
    公共类用户
    {
    公共int Id{get;set;}
    公共虚拟ICollection组{get;set;}
    }
    
    EF知道这是一种多对多关系,将创建关联表(UsersGroups),但您不需要关联实体

    编辑


    很少需要设置
    db.Entry(myEntity.State=EntityState.Modified使用EF6。代理工作得很好。

    ToList()
    更改为normali
    foreach
    没有任何区别。如果添加了“状态”而没有更改,听起来像是实体断开连接的问题。我的猜测是EF正在重新创建“GroupUser”,然后在尝试保存时将前一个“GroupUser”置零。您是否尝试打印以前添加的用户的值?
    public class User
    {
        public int Id { get; set; }
        public virtual ICollection<Group> Groups { get; set; }
    }