【问题标题】:EF6 Code First many-to-many without collectionsEF6 Code First 多对多无集合
【发布时间】:2015-02-04 05:33:53
【问题描述】:

所以我在 EF 中有以下模型:

public class User: IEntity
{
    public Guid Id { get; protected set; }
    public string Email { get; protected set; }
    internal User()
    {
    }

    public User(Guid id, string email)
    {
        Id = id;
        Email = email;
    }
}

public class Tenant : IEntity
{
    public Guid Id { get; protected set; }
    public string Name { get; protected set; }

    internal Tenant() { }

    public Tenant(Guid id, string name)
    {
        Id = id;
        Name = name;
    }
}

我想在这些实体之间建立多对多关系,而不需要在其中包含集合。

我尝试过创建一个连接实体,例如:

public class TenantUser
{
    public int Id { get; set; }
    public virtual Tenant Tenant { get; set; }
    public virtual User User { get; set; }

    internal TenantUser ()
    {
    }

    public TenantUser(Tenant tenant, User user )
    {
        this.Tenant = tenant;
        this.User = user;
    }
}

使用以下设置:

modelBuilder.Entity<TenantUser>()
   .HasRequired<Tenant>(m => m.Tenant)
   .WithMany();

modelBuilder.Entity<TenantUser>()
   .HasRequired<User>(m => m.User)
   .WithMany();

当我保存 TenantUser 对象时,数据库会填充正确的外键。当我在 TenantUser DbSet 中查询所有行时,它会返回所有行,但我只填充了 Id 值,Tenant 和 User 都是 null。

我尝试将 TenantId 和 UserId 字段添加到 TenantUser,然后为这些字段执行 HasForeignKey,但没有任何区别;查询时填充了 TenantId 和 UserId,但 Tenant 和 User 仍然为空。

我觉得我在这里遗漏了一些简单的东西。任何想法都会很棒:)

【问题讨论】:

  • 我有点不确定你想在这里建立什么样的关系?您能否用文字描述您所追求的关系,或者如果更容易发布关系的数据库图。
  • 问题可能只是您在查询表时(而不是在配置本身中)没有包括UserTenant。我不确定是否可以配置,但请尝试使用ctx.TenantUsers.Include(tu =&gt; tu.Tenant).Include(tu =&gt; tu.User) 进行查询。
  • 这还不清楚。你是什​​么意思你想要多对多没有集合?除了将其他项放在某种集合中之外,还有什么其他方法可以引用与许多其他项有关系的对象?
  • 抱歉,如果不清楚,但我的意思是租户或用户实体中没有集合属性。基本上一个普通的 SQL 连接表是如何工作的。这里最典型的情况是我会通过 User.Id 查询 TenantUser 并将 Tenant 选择到 IEnumerable 中。我觉得 sriban 的答案是赢家,但我暂时无法对其进行测试。

标签: c# entity-framework code-first


【解决方案1】:

如果你想要多对多,那么删除配置:

modelBuilder.Entity<TenantUser>()
.HasRequired<Tenant>(m => m.Tenant)
.WithMany();

modelBuilder.Entity<TenantUser>()
.HasRequired<User>(m => m.User)
.WithMany();

为什么?因为EF使用协议:

public class User: IEntity
{
    public Guid Id { get; protected set; }
}

public class Tenant : IEntity
{
    public Guid Id { get; protected set; }
}

public class TenantUser
{
    public int Id { get; set; }
    public virtual Tenant Tenant { get; set; }
    public virtual User User { get; set; }
}

这是流畅的多对多。

当您进行查询时,请使用:

public class UnitOfWork : DbContext
{
    public IDbSet<User> Users { get; set; }
    public IDbSet<Tenant> Tenants { get; set; }
    public IDbSet<TenantUser> TenantUsers { get; set; }
}

context.TenantUsers.Include(e => e.Tenant).Include(e => e.User);

然后 EF 将它们包含在映射中

【讨论】:

  • 看起来可行,谢谢。不过,快速提问。我没有看到采用 lambda 表达式的 Include 方法,我只看到采用字符串的 Include 方法。如果我这样做 Include("Tenant").Include("User") 它可以工作。这是你的意思,还是有一个扩展方法可以让我使用表达式? (首选)
  • 没关系,我在System.Data.Entity 找到了它。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-07
  • 1970-01-01
  • 2013-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多