2016-09-21 6 views
2

私はここでこの性質について質問しましたが、実際にこの問題を完全にまたは正しく解決するものはありません。エンティティと複合型キャストへのLinq

...その後、私はこのようなメソッドを持っている... ...私は、次のコードを持って、私はチェックを追加したいというメソッドに

public override IQueryable<T> GetAll() 
{ 
    return base.GetAll(); 
} 

public interface IHaveRoles { 
    ICollection<Role> Roles { get;set; } 
} 

public class Foo : IHaveRoles { 
    public ICollection<Role> Roles { get;set; } 
} 

public class Bar { } 

とさせて頂きますそれは... ...

if(typeof(IHaveRoles<Role>).IsAssignableFrom(typeof(T))) { 
     return base.GetAll() 
      .Where(i => i.Roles.Any(r => r.Users.Any(u => u.Id == User.Id))); 

} 

を私のIQueryableに簡単な句を追加し、動的に私の中でを生じる可能性がそれはどこの句がそれ自身の権利であれば簡単だし、設計時にTが何であるか分かっていれば、これは問題ではないだろう。

私は私の句を追加終わりだとき、私はもはやIHaveRolesとして戻っIQueryable<T>にキャストすることはできませんので、しかし、IQueryable<IHaveRoles>resultをキャストすることはオプションではありませんがT

のサブタイプではないので、どのように行いますこれらのような他の質問に与えられた回答の一部に示すように、我々は... IQueryable<T>と違法キャストせずに返却する能力を保持しながら、この問題を解決

Cast Entity to Implemented Interface in a Generic Method Using LINQ for Entity Framework

LINQ-to-entities casting issue

...とEFはプリミティブ型をEDMないサポートしていないとの問題を回避方法で...

LINQ to Entities only supports casting EDM primitive or enumeration types with IEntity interface

EDIT:いくつかのテストの実装...

public override IQueryable<T> GetAll() 
{ 
    var result = base.GetAll(); 

    if (typeof(IHaveRoles).IsAssignableFrom(typeof(T)) && !AuthInfo.SignatureIsValid) 
    { 
     // tried implementations that don't work ... 

     // InvalidCastException (CLR can't cast an IQueryable<IHaveRoles> to a IQueryable<T> 
     var queryableRoleSecured = ((IQueryable<IHaveRoles>)result); 
     result = (IQueryable<T>)queryableRoleSecured 
      .Where(i => i.Roles.Any(r => User.Roles.Contains(r))); 

     // NotSupportedException (EF won't accept this kind of casting) 
     result = result 
      .Where(i => ((IHaveRoles)i).Roles.Any(r => r.Users.Any(u => u.Id == User.Id))); 
    } 

    return result; 
} 

答えて

2

うわー、私は決してそのダイナミックなlinqが一見無制限になっているように見えますが、ここに再びあります。

ここでは、動的に同じ設計時のルールは、私は少しで(私が欲しかったまったく同じLINQを適用することができることを意味し、適用されません実行時に評価されているので、私は

public override IQueryable<T> GetAll() 
{ 
    var result = base.GetAll(); 

    if (typeof(IHaveRoles).IsAssignableFrom(typeof(T)) && !AuthInfo.SignatureIsValid) 
     result = result.Where("Roles.Any(Users.Any(Id == @0))", User.Id); 

    return result; 
} 

...思い付いたものですもちろんオーバーヘッドコストのビット)。

関連する問題