Я пытаюсь создать универсальный класс для работы с сущностями из EF. Этот класс общается с репозиториями, но именно этот класс создает выражения, отправляемые в репозитории. Во всяком случае, я просто пытаюсь реализовать один виртуальный метод, который будет служить основой для общих запросов. В частности, он примет a int
и ему нужно только выполнить запрос по первичному ключу рассматриваемой сущности.
Я крутился с ним и создал отражение, которое может или не может работать. Я говорю это, потому что я получаю NotSupportedException
с сообщением LINQ to Entities не распознает метод «System.Object GetValue (System.Object, System.Object [])», и этот метод не может быть переведен в выражение хранилища. Итак, я попробовал другой подход, и он выдал то же исключение, но с ошибкой Тип узла выражения LINQ 'ArrayIndex' не поддерживается в LINQ to Entities. Я знаю, что это потому что EF не будет анализировать выражение так, как L2S.
В любом случае, я надеюсь, что кто-то с немного большим опытом может указать мне правильное направление в этом. Я публикую весь класс с обеими попытками.
public class Provider<T> where T : class {
protected readonly Repository<T> Repository = null;
private readonly string TEntityName = typeof(T).Name;
[Inject]
public Provider(
Repository<T> Repository) {
this.Repository = Repository;
}
public virtual void Add(
T TEntity) {
this.Repository.Insert(TEntity);
}
public virtual T Get(
int PrimaryKey) {
// The LINQ expression node type 'ArrayIndex' is not supported in
// LINQ to Entities.
return this.Repository.Select(
t =>
(((int)(t as EntityObject).EntityKey.EntityKeyValues[0].Value) == PrimaryKey)).Single();
// LINQ to Entities does not recognize the method
// 'System.Object GetValue(System.Object, System.Object[])' method,
// and this method cannot be translated into a store expression.
return this.Repository.Select(
t =>
(((int)t.GetType().GetProperties().Single(
p =>
(p.Name == (this.TEntityName + "Id"))).GetValue(t, null)) == PrimaryKey)).Single();
}
public virtual IList<T> GetAll() {
return this.Repository.Select().ToList();
}
protected virtual void Save() {
this.Repository.Update();
}
}
ОБНОВЛЕНИЕ для @ Gabe
Вот как выглядит мой класс хранилища:
public class Repository<T> where T : class {
protected readonly ObjectContext ObjectContext = null;
private readonly IObjectSet<T> ObjectSet = null;
[Inject]
public Repository(
ObjectContext ObjectContext) {
this.ObjectContext = ObjectContext;
this.ObjectSet = this.ObjectContext.CreateObjectSet<T>();
}
public virtual void Delete(
T Entity) {
this.ObjectSet.DeleteObject(Entity);
}
public virtual void Insert(
T Entity) {
this.ObjectSet.AddObject(Entity);
}
public virtual IQueryable<T> Select() {
return this.ObjectSet;
}
public virtual IQueryable<T> Select(
Expression<Func<T, bool>> Selector) {
return this.ObjectSet.Where(Selector);
}
public virtual void Update() {
this.ObjectContext.SaveChanges();
}
}
Имена методов основаны на функциях SQL, а не на методах LINQ, поэтому я думаю, что вы не понимаете, как работает мой репозиторий.