У меня есть уровень репозитория, к которому мои приложения обращаются, который можно инициализировать с помощью IDataSource
; например LinqToSqlDataSource, EntityFrameworkDataSource и т. Д. ...
IDataSource предоставляет методы для вставки, обновления, удаления и запроса источника данных соответственно. Относительно этого вопроса является то, что FindAll<T>
возвращает IQueryable<T>
.
Все мои базовые сущности реализуют простой интерфейс, чтобы сделать поиск сущностей по идентификатору универсальным и удобным;
public interface IAmIdentifiable<T>
{
T Id { get; set; }
}
Ниже приведен соответствующий код для метода FindById<T, TKey>
, с которым у меня возникают проблемы в EntityFramework.
public class Repository
{
public Repository(IDataSource dataSource)
{...}
public T FindById<T, TKey>(TKey identifier) where T : class, IAmIdentifiable<TKey>
{
return _DataSource.FindAll<T>().SingleOrDefault(i => i.Id.Equals(identifier));
}
...
}
Этот FindById<T, Tkey>(...)
отлично работает с LinqToSql, но не работает в EntityFramework 4 .
Пример использования
User user = Repository.FindById<User, int>(someUserId);
Message msg = Repository.FindById<Message, Guid>(someMessageId);
Когда приведенный выше код запускается с реализацией IDataSource EntityFramework 4, он выдает следующую ошибку:
Невозможно создать постоянное значение типа 'System.Object'. В этом контексте поддерживаются только примитивные типы (такие как Int32, String и Guid).
Я попытался изменить это, чтобы выполнить сравнение == для типов значений. Я прочитал, что окольный способ ограничения универсального значения на тип значения состоит в ограничении struct
. Я обновил базовый интерфейс для всех сущностей и средства поиска репозитория соответственно ...
public interface IAmIdentifiable<T> where T : struct
{
T Id { get; set; }
}
public T FindById<T, TKey>(TKey identifier)
where T : class, IAmIdentifiable<TKey>
where TKey : struct
{
return _DataSource.FindAll<T>().SingleOrDefault(i => i.Id == identifier);
}
Однако это все равно приводит к ошибке компиляции;
Ошибка 59 Оператор '==' не может быть применен к операндам типа 'TKey' и 'TKey'
Кто-нибудь может пролить некоторый свет на то, как я мог бы привести приведение этих сущностей к интерфейсу IAmIdentifiable<T>
, чтобы иметь общий способ получения сущностей по Id?