1

我有两个用户界面:

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>;
}

我有根据条件表达式检索一个用户的方法:

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。

我错过了什么?我没有收到任何错误/警告,并且我确保我的继承正确完成(或者至少我认为是这样)。

如果代码有一些拼写错误,我很抱歉,我在工作中留下了真实的代码。

感谢所有的提示。

4

2 回答 2

2

Entity Framework 需要知道您投影到的通用参数可以是普通的 ol' 对象或某种类型的结构,否则它只能将其推断为IUserModel. 如果您添加另一个类型约束,告诉它T始终是其中之一(取决于您的域模型;您可能正在使用类):

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

(或者这个,如果你所有的IUserModels 都是结构:)

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

该异常应该消失。

请参阅这两个主题,我在其中找到了答案:

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 回答