当前位置: 首页 > 知识库问答 >
问题:

创建具有多对多关系的实体的副本,而不复制类型之一

柯良骏
2023-03-14

我有问题与复制实体与多对多的关系。我有三个实体公司,角色和用户定义如下:

public class Company
{
    public int Id { get; set; }

    public string Name { get; set; }

    public virtual IList<User> Users { get; set; }
}
public class User
{
    public int Id { get; set; }

    public string Name { get; set; }

    public virtual IList<Role> Roles { get; set; }
}
public class Role
{
    public int Id { get; set; }

    public string Name { get; set; }

    public virtual IList<User> Users { get; set; }
}
public class UserConfiguration : EntityTypeConfiguration<User>
{
    public UserConfiguration()
    {
        ToTable("TUser");
        HasKey(x => x.Id);

        HasMany(x => x.Roles).WithMany(x => x.Users).Map(m =>
        {
            m.MapLeftKey("UserId");
            m.MapRightKey("RoleId");
            m.ToTable("TUserRole");
        });
    }
}

我使用迁移在db中创建表,显然EF创建了TUserRole表(到目前为止一切都很好)。

现在,我想创建company和users的副本,但不复制角色(所以我想在TCompany、TUser和TUserRole表中创建新记录,但在TRole中不创建新记录)。

我以为这样的方法会奏效,但我遇到了例外:

Context context = new Context();

var company = context.Companies.Include(x => x.Users.Select(u => u.Roles)).AsNoTracking().SingleOrDefault();

context.Companies.Add(company);

foreach (var user in company.Users)
{
    foreach (var role in user.Roles)
    {
        context.Entry(role).State = EntityState.Unchanged;
    }
}

context.SaveChanges();

我用的是EF 6.1.3。

共有1个答案

何升
2023-03-14

使用AsnoTracking通常是获得未附加到上下文的实体图的好主意。如您所知,将根实体(company)添加到一个新的上下文中会将图中的所有实体标记为Added,复制实体是小菜一碟。

但有一个令人沮丧的地方。AsnoTracking使EF为结果集中的每个实体物化一个新对象,因为它无法跟踪实体是否已经物化。因此,只要对象图只偏离根实体,就可以了。即。只要所有关联都1-0..n。如果是这样的话,图中的所有实体都将代表一个“真实的”实体。

但是,在您的示例中,用户角色之间存在M-N关联。图收敛。如果一些用户具有相同的角色,EF将在使用AsnoTracking时创建重复的Role对象

这里的方法是通过一个上下文查询对象图,作为POCO,而不是代理,然后将其添加/附加到第二个上下文:

Company company;
using (Context context = new Context())
{
    context.Configuration.ProxyCreationEnabled = false;
    company = context.Companies.Include(x => x.Users.Select(u => u.Roles))
                     .SingleOrDefault();
}

using (Context context = new Context())
{
    context.Companies.Add(company);

    foreach (var user in company.Users.SelectMany(u => u.Roles)
                                .Distinct())
    {
        context.Entry(role).State = EntityState.Unchanged;
    }

    context.SaveChanges();
}

代理对创建它们的上下文有一个引用,因此不能将它们附加到第二个上下文。

 类似资料:
  • 问题内容: 有一个实体类“ A”。A类可能具有相同类型“ A”的子级。如果“ A”是孩子,则也应保留它的父母。 这可能吗?如果是这样,我应该如何在Entity类中映射关系?[“ A”有一个id列。] 问题答案: 是的,这是可能的。这是标准双向@ManyToOne/ @OneToMany关系的特例。之所以特别是因为关系两端的实体都是相同的。JPA 2.0规范的第2.10.2节详细介绍了一般情况。 这

  • 我有一个JPA实体(人)与其他实体(地址)有多对一的关系。在一个对象可以被系统使用之前,这个对象必须得到主管的批准。我将原始实体存储为byte[]并对“工作”实体进行更改,并将其存储在数据库中。如果这些更改不被批准,我必须恢复原始状态。因此,我将存储的原始数据从byte[]中转换出来,并使用实体管理器将其合并到数据库中。所有的工作都很好,但是如果一个新的地址实体已经添加到“工作”的人,在合并还原的

  • 我很难找到数据库中多对多关系的最佳设计。我的项目允许用户创建我们所说的日志警报。日志警报将检查给定的日志是否满足某些标准,如果满足,它将向AWS SNS主题发送消息。我想做的是将日志警报与AWS SNS主题联系起来。我还想将哪个用户分配日志警报与AWS SNS主题联系起来。

  • DBSchema-2表(用户和角色)具有多对多关系,并由postgres中的中间表(用户角色)桥接。我想获取所有角色和创建它的人的姓名。名称在用户表中可用,但所有其他详细信息在角色表中。Roles表中有一个由创建人(创建角色的人的用户id)创建的字段。 我正在尝试构建一个GET请求,以查看给定id的所有角色以及创建id的人的姓名 实体类Users1.java 实体类角色。JAVA 角色。存储库类

  • 我使用下面的代码创建了20篇帖子,每个帖子都有3条评论。 相反,我想创建20个帖子,每个帖子都有随机数量的评论(例如,帖子1有2个评论,帖子2有4个评论,等等)。) 这不起作用,每个帖子都有相同(随机)数量的评论。 我怎样才能做到这一点?

  • 如何为这种多对多关系分配默认值?制作两个关联表->一个用于收件箱-关系,另一个用于发件箱-关系会更好吗?我该如何做到这一点?这个问题的其他解决方案? 任何帮助都非常感谢--非常感谢!