1

ユーザー用のインターフェイスが 2 つあります。

public interface IUserModel
{
    int UserId {get;set;}
}

public interface IUserAuthModel : IUserModel
{
    string Username {get;set;}
    string Password {get;set;}
}

アクセスの承認チェックが必要なため、IUserAuthModel を実装するユーザー モデルがあります。

public class UserSubscriptionModel : IUserAuthModel
{
    public int UserId {get;set;}
    public string Username {get;set;}
    public string Password {get;set;}
    public bool Subscribed {get;set;}
}

プロジェクションの方法があるEF 4.3.1に基づくユーザーリポジトリがあります。

IQueryable<T> ProjectTo<T>() where T: IUserModel
{
    if(typeof(T) == typeof(UserLoginModel)
    {
        return db.Users.Select(x => new UserSubscriptionModel {
        UserId = x.UserId,
        Username = x.Username,
        Password = x.Password,
        Subscribed = x.Subscribed
    }) as IQueryable<T>;
}

条件式に基づいて 1 人のユーザーを取得するメソッドがあります。

T Get<T>(conditionalexpression) where T : IUserModel
{
    return ProjectTo<T>.Where(conditionalexpression).FirstOrDefault();
}

私は認証方法を実装しています:

public bool Authorize<T>(string username, string password, out T TUser) where T : IUserAuthModel
{
    TUser = Get<T>(x => x.Username == username && x.Password == password);
     ... some other irrelevant code
}

そして、私は次のことを行います:

UserSubscriptionModel model;
bool authorized = Authorize<UserSubscriptionModel>("hello","world", out model);

このコードは、FirstOrDefault を抽出しようとする部分で失敗します。Linq to Entities はプリミティブ型のキャストをサポートしていると書かれています.... UserSubscriptionModel から IUserAuthModel にキャストできません - または、他の方法では覚えられません。ただし、IUserAuthModel が IUserModel から継承されているにもかかわらず、ジェネリックが機能していないため、クラスが IUserAuthModel を実装すると、IUserModel も実装されます。

私は何が欠けていますか?エラー/警告は 1 つも表示されず、継承が適切に行われていることを確認しました (または、少なくともそう思います)。

コードにタイプミスがある場合は申し訳ありませんが、実際のコードをそのまま残しました。

すべてのヒントをありがとう。

4

2 に答える 2

2

Entity Framework は、投影先のジェネリック パラメーターが単純なオブジェクトまたは何らかの型の構造体である可能性があることを認識する必要がありますIUserModel。別の型制約を追加するTと、常にそれらのいずれかになります (ドメイン モデルによって異なりますが、おそらくクラスを使用しているはずです)。

IQueryable<T> ProjectTo<T>() where T: class, IUserModel

(または、すべてのIUserModels が構造体の場合:)

IQueryable<T> ProjectTo<T>() where T: struct, IUserModel

その例外はなくなるはずです。

答えが見つかった次の 2 つのトピックを参照してください。

https://stackoverflow.com/a/13701650/183350

https://stackoverflow.com/a/19847671/183350

于 2015-01-09T17:41:44.003 に答える
0

IQueryable として返す代わりに、linq Cast<> を試してください

IQueryable<T> ProjectTo<T>() where T: IUserModel
{
    if(typeof(T) == typeof(UserLoginModel)
    {
        return db.Users.Select(x => new UserSubscriptionModel {
        UserId = x.UserId,
        Username = x.Username,
        Password = x.Password,
        Subscribed = x.Subscribed
    }).Cast<T>;
}
于 2013-07-17T16:11:58.247 に答える