Linq到实体和泛型 - 无法投射

时间:2012-06-27 16:36:39

标签: entity-framework generics interface linq-to-entities

我有两个用户界面:

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的用户存储库,我有投影方法:<​​/ p>

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。

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

如果代码有错误,我很抱歉,我在工作中留下了真正的代码。

感谢您的所有提示。

2 个答案:

答案 0 :(得分:1)

实体框架需要知道您投射到的通用参数可以是一个普通的参数。某种类型的对象或结构,否则它只能将其推断为IUserModel。如果你添加另一个类型约束,告诉它T将永远是其中之一(取决于你的域模型;你可能会使用类):

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

(或者,如果您的所有IUserModel都是结构符号:),

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

该异常应该消失。

请参阅以下两个主题,我找到了答案:

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

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

答案 1 :(得分:0)

而不是返回IQueryable尝试linq Cast&lt;&gt;

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