2016-05-31 36 views
1

我有三個類UserRoleUserRoleEF代碼第一個例外實體類型不是使用簡單Odata客戶端的當前上下文的模型的一部分

使用代碼首先,我創建的表像之下

DbContext.cs 
rotected override void OnModelCreating(DbModelBuilder modelBuilder) 
     { 
      Database.SetInitializer<CodeFirstDBContext>(null); 

    modelBuilder.Entity<DomainModels.Security.User>().HasKey(x => x.Id); 
      modelBuilder.Entity<DomainModels.Security.User>().Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 

       modelBuilder.Entity<DomainModels.Security.Role>().HasKey(x => x.Id); 
      modelBuilder.Entity<DomainModels.Security.Role>().Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 


// UserRoles table column names as UserId and RoleId instead of default created by ER as User_Id and Role_Id. 
      modelBuilder.Entity<DomainModels.Security.User>().HasMany(x => x.Roles).WithMany(y => y.Users).Map(
      of => 
      { 
       of.MapLeftKey("UserId"); 
       of.MapRightKey("RoleId"); 
       of.ToTable("UserRoles"); 
      }); 
} 

public virtual DbSet<DomainModels.Security.Role> Roles { get; set; } 
public virtual DbSet<DomainModels.Security.User> Users { get; set; } 

不添加UserRole DbSet因爲它是由EF在很多創造了許多關係

我的問題是,當我嘗試執行任何上UserRole CRUD操作拋出異常:

的實體類型的UserRole不是型號爲當前上下文的一部分0我們使用simple odata

var resul = await odataclient.For<UserRole>().Set(new { UserId = userId, RoleId = roleId }).InsertEntryAsync(); 

我不知道Simple OData Client是否支持此與否。 我該怎麼辦?

+0

你更新數據庫的理解? – tmg

+0

是的我已經更新數據庫成功! – Neo

回答

2

您所設置的是EF爲您維護的自動「鏈接」表,所謂的多對多關係。在這樣的配置下UserRole實體不存在。該模型應該是這樣的:使用導航屬性User.RolesRole.Users的任何一個

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

    // other properties 
    // ... 

    // UserRole association 
    public virtual ICollection<Role> Roles { get; set; } 
} 

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

    // other properties 
    // ... 

    // UserRole association 
    public virtual ICollection<User> Users { get; set; } 
} 

您執行CRUD上的UserRole表。

編輯:或者,你可以保持UserRole實體和使用明確的鏈接表有兩個one-to-many協會這樣的:

型號:

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

    // other properties 
    // ... 

    // UserRole association 
    public virtual ICollection<UserRole> UserRoles { get; set; } 
} 

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

    // other properties 
    // ... 

    // UserRole association 
    public virtual ICollection<UserRole> UserRoles { get; set; } 
} 

public class UserRole 
{ 
    public int UserId { get; set; } 
    public int RoleId { get; set; } 
    public virtual User User { get; set; } 
    public virtual Role Role { get; set; } 
} 

的DbContext:

public virtual DbSet<DomainModels.Security.Role> Roles { get; set; } 
public virtual DbSet<DomainModels.Security.User> Users { get; set; } 
public virtual DbSet<DomainModels.Security.UserRoles> UserRoles { get; set; } 

配置:

modelBuilder.Entity<DomainModels.Security.UserRole>() 
    .HasKey(x => new { x.UserId, x.RoleId }); 

modelBuilder.Entity<DomainModels.Security.UserRole>() 
    .HasRequired(x => x.User) 
    .WithMany(y => y.UserRoles) 
    .HasForeignKey(x => x.UserId) 
    .WillCascadeOnDelete(); 

modelBuilder.Entity<DomainModels.Security.UserRole>() 
    .HasRequired(x => x.Role) 
    .WithMany(y => y.UserRoles) 
    .HasForeignKey(x => x.RoleId) 
    .WillCascadeOnDelete(); 

有了這個配置,你可以使用你原來的CRUD的設計。

+1

非常感謝,但我們正在使用Simple Odata客戶端插入/更新如何使用它? – Neo

+0

我不明白這個問題。如何使用什麼? –

+0

我已經詳細更新了我的問題,以前我們直接使用'UserRole'模型,並且使用simpleOdata Client,我們可以直接插入/更新/刪除,現在我們正在使用EF與汽車「鏈接」的多對多關係'我們不能直接使用'UserRole'它會給出例外。我不確定是否簡單Odata客戶端支持或不支持 – Neo

2

許多一對多EF不能作爲實際獲得的實體,而你必須要麼使用所涉及的實體它執行操作,相關的實體可作爲兩個ICollection的模型。 EF不公開此實體,而是在內部管理它。

即,你必須有ICollection<User> Users *在* Role反之亦然導航屬性。

比方說,您有一個User的對象,您需要獲取/設置角色。你將不得不這樣做的:

User user = GetSomeUser(); 
Role adminRole = GetAdminRole(); 
user.Roles.Add(adminRole); 

Role role = user.Roles.Where(x => x.Id == adminRoleId).firstOrDefault(); 

上面的例子只是給你一個如何使用Many-to-Many關係EF工作

相關問題