2014-12-02 26 views
0

我有以下实体类/模型。EF在许多关系中添加不需要的字段

public class AppUser : IdentityUser<int, AppUserLogin, AppUserRole, AppUserClaim>, IUser<int> 
    { 
    // has inherited property : public int Id 
     public virtual ICollection<TenantAdmin> TenantAdmins { get; set; } 
     ... 
    } 

     public class Tenant 
    { 
     public int Id { get; set; } 
     public virtual ICollection<TenantAdmin> TenantAdmins { get; set; } 
     ... 
    } 

我有绑起来

public class TenantAdmin 
    { 
     public int AppUserId { get; set; } 
     public virtual AppUser AppUser { get; set; } 
     public int TenantId { get; set; } 
     public virtual Tenant Tenant { get; set; } 
    } 

类,并在我的DbContext类

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    base.OnModelCreating(modelBuilder); 
    modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); 

    modelBuilder.Entity<TenantAdmin>().HasKey(x => new { x.TenantId, x.AppUserId }); 
    ... 
} 

的许多一对多的关系,正常工作下,该数据库有字段,键/ fkeys我期望。 当我删除一个appuser时,我得到了错误(这是预期的),我应该在链接上配置cascadedelete。

我在我的OnModdeling中尝试了额外代码的不同组合,但到目前为止他们都有恼人的结果,第二个AppUserID和TenantId被添加到TenantAdmin表中。即使我删除了双键定义并向TenantAdmin类添加了Id属性。

modelBuilder.Entity<Tenant>().HasMany(x => x.TenantAdmins).WithOptional().WillCascadeOnDelete(true); 
modelBuilder.Entity<AppUser>().HasMany(x => x.TenantAdmins).WithOptional().WillCascadeOnDelete(true); 

我想完成什么? 无需任何TenantAdmin即可自由创建AppUser,Tenant。仅当相应的AppUser和Tenant存在时才创建TenantAdmin。删除AppUser时,所有关联的TenantAdmin都会被删除(删除Tenant时也是如此)。做这件事的最佳做法是什么?

任何链接到一个很好的完整的解释.WithOptional .Required .....与样本将不胜感激。 Google迄今为止没有带给我我期待的内容。

+0

一些观察。第二个AppUserID和TenantID字段的数据类型是什么?他们是int吗? (可空值)?其次,不应该将两个关系中的TenantAdmin方面标记为必需且不可选,因为相应外键字段的数据类型是不可空的? – 2014-12-02 15:14:05

+0

数据类型是int。通过明确定义TenantId和AppUserId作为外键(通过装饰类或通过流畅的API),它被解决了。不知怎的,“约定配置”无法完成这项工作。 – BrilBroeder 2014-12-02 18:06:00

回答

1
modelBuilder.Entity<TenantAdmin>().HasKey(x => new { x.TenantId, x.AppUserId }); 

但是外键呢?你没有告诉EF你已经有了外键字段。 因此产生一个持有导航关系/ s的

modelBuilder.Entity<TenantAdmin>.HasRequired(t => t.Tenant) 
      .WithMany() 
      .HasForeignKey(fk => fk.TenantId) ; 

重复那些已经有一个外键字段等导航属性。

+0

Thx。这实际上是解决方案。我不明白为什么'约定优于配置'在这种情况下不能解决这个问题。 – BrilBroeder 2014-12-03 12:38:05

+0

你可以使用注释或流利的API来说这个字段是我的外键。我猜为什么它没有按惯例完成是由于可选与所需的外键问题。但这是EF开发者的一个问题。 – 2014-12-03 14:41:39