2017-06-30 15 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()私はRole Proxyオブジェクトを持つUserオブジェクトを取得します。

ロールオブジェクトを持つユーザーオブジェクトが必要です。 どうすればいいですか?おかげ

+0

私は興味がありますが、なぜプロキシオブジェクトではないのですか?とにかく「役割」の子孫です。 – Alisson

+0

私はJSONとしてユーザーを送る必要があります。 'Ok(user)'は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へのあなたのデータベース・エンティティの公開を回避することです。

// 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

関連する問題