我有两个用户界面:
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。
我错过了什么?我没有收到任何错误/警告,我确保我的继承正确完成(或者至少我认为是这样)。
如果代码有错误,我很抱歉,我在工作中留下了真正的代码。
感谢您的所有提示。
答案 0 :(得分:1)
实体框架需要知道您投射到的通用参数可以是一个普通的参数。某种类型的对象或结构,否则它只能将其推断为IUserModel
。如果你添加另一个类型约束,告诉它T
将永远是其中之一(取决于你的域模型;你可能会使用类):
IQueryable<T> ProjectTo<T>() where T: class, IUserModel
(或者,如果您的所有IUserModel
都是结构符号:),
IQueryable<T> ProjectTo<T>() where T: struct, IUserModel
该异常应该消失。
请参阅以下两个主题,我找到了答案:
答案 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>;
}