2017-06-30 166 views
1

負載對象我有一個角色的實體的用戶,我需要與我們的角色(而不是代理對象)來加載用戶。實體框架 - 與相關對象

class User{ 
    public int Id{get; set;} 
    public string Name{get; set;} 
    public ICollection<Role> Roles{get; set;} 
} 
class Role{ 
    public int Id{get; set;} 
    public string Name{get; set;} 
    public virtual User User{get; set;} 
} 

當我使用這個:DbContext.Users.Where(x => x.Id == id).Include(x => x.Roles).FirstOrDefault()我得到帶有角色代理對象的用戶對象。

我需要的角色對象的用戶對象。 如何做到這一點?由於

+0

我只是好奇,但爲什麼不能像代理對象?無論如何,它都是「角色」的後代。 – Alisson

+0

我需要發送用戶的JSON和'好了(用戶)'不代理對象添加到JSON(必須) – bluray

回答

1

回答您的具體回答,只是禁止代理的創建只是一個特定的代碼塊,但你必須渴望負荷您的實體,像這樣:

try 
{ 
    DbContext.Configuration.ProxyCreationEnabled = false; 
    var userWithRoles = DbContext.Users.Include(x => x.Roles).Where(x => x.Id == id).FirstOrDefault(); 
} 
finally 
{ 
    DbContext.Configuration.ProxyCreationEnabled = true; 
} 

...這將隻影響該實例。我把它封裝在try finally塊中,因爲如果在加載實體時發生任何異常,你可以確保這個選項將被顛倒。

您也可以將您的DbContext構造函數中設置此全球範圍內,但我不建議這樣做:

public class YourDbContext : DbContext 
{ 

    public YourDbContext() : base("name=ConnectionString") 
    { 
     this.Configuration.ProxyCreationEnabled = true; 
    } 
} 

我的建議是爲了避免暴露你的數據庫實體的API。您可以創建DTO類並將它們公開:

// original entities 
public class User { 
    public int Id{get; set;} 
    public string Name{get; set;} 
    public ICollection<Role> Roles{get; set;} 
    // other fields like birthdate, status, password, etc... 
} 
public class Role { 
    public int Id{get; set;} 
    public string Name{get; set;} 
    public virtual User User{get; set;} 
} 

// DTO classes, keeping only the fields you want 

// original entities 
public class UserDTO { 
    public int Id{get; set;} 
    public string Name{get; set;} 
    public ICollection<RoleDTO> Roles{get; set;} 
} 
public class RoleDTO { 
    public int Id{get; set;} 
    public string Name{get; set;} 
} 

// project them like this: 
var userDTO = DbContext.Users.Where(x => x.Id == id) 
    .Select(u => new UserDTO 
    { 
     Id = u.Id, 
     Name = u.Name, 
     Roles = u.Roles.Select(r => new RoleDTO 
     { 
      Id = r.Id, 
      Name = r.Name 
     }), 
    }) 
    .FirstOrDefault(); 

然後,您可以僅返回DTO。有像AutoMapper這樣的工具使項目DTO類變得更容易和更清潔,這只是一個例子。

+0

好它的好,但我使用依賴注入,我不能在全球範圍內使用ProxyCreationEnabled。 – bluray

+0

因此,使用它後請將其改回。我在編輯我的答案... – Alisson

+0

是的!這很好。當我設置'proxyCreationEnabled = false'時,它可以工作。這是最好的解決方案?我想使用Join方法也許或其他linq方法... – bluray