2012-06-27 3 views
1

У меня есть два интерфейса для пользователей:Linq субъектов и дженерик - не в состоянии бросить

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

У меня есть метод d, который извлекает одного пользователя на основе условного выражения:

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

Как ваш код потерпеть неудачу, если нет ошибки/предупреждения? Нет данных? –

+0

Вы пробовали 'IQueryable ProjectTo () где T: IUserModel'. См. [Ковариация и контравариантность] (http://msdn.microsoft.com/en-us/library/dd799517.aspx). Просто выстрел. – NinjaNye

+0

@GertArnold Я подозреваю, что OP означает, что они не получали никаких ошибок/предупреждений компилятора. Это объясняет исключение во время выполнения. –

ответ

0

вместо возвращения в IQueryable попробовать в ролях < LINQ>

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

Entity Framework необходимо знать, что общий параметр, который вы осуществляете, чтобы может быть простой ол»объект или структура некоторого типа, в противном случае он сможет сделать это как IUserModel. Если добавить еще один тип ограничения, говоря это T всегда будет одна из тех вещей (в зависимости от модели предметной области, вы, вероятно, с помощью классов, хотя):

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

(или это, если все ваши IUserModel s являются структурами :)

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

это исключение должно исчезнуть.

См эти две темы, где я нашел ответ:

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

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

Смежные вопросы