для целей контроля доступа в интенсивной системе БД я должен был реализовать оболочку объектов, где будет проверяться AC.
Основная цель заключается в том, чтобы это изменение сохраняло существующий код для доступа к базе данных, который реализован с помощью linq для сущностей по всем классам (для базы данных нет централизованного уровня).
Созданный ObjectSetWrapper выглядит следующим образом:
public class ObjectSetWrapper<TEntity> : IQueryable<TEntity> where TEntity : EntityObject
{
private IQueryable<TEntity> QueryableModel;
private ObjectSet<TEntity> ObjectSet;
public ObjectSetWrapper(ObjectSet<TEntity> objectSetModels)
{
this.QueryableModel = objectSetModels;
this.ObjectSet = objectSetModels;
}
public ObjectQuery<TEntity> Include(string path)
{
return this.ObjectSet.Include(path);
}
public void DeleteObject(TEntity @object)
{
this.ObjectSet.DeleteObject(@object);
}
public void AddObject(TEntity @object)
{
this.ObjectSet.AddObject(@object);
}
public IEnumerator<TEntity> GetEnumerator()
{
return QueryableModel.GetEnumerator();
}
public Type ElementType
{
get { return typeof(TEntity); }
}
public System.Linq.Expressions.Expression Expression
{
get { return this.QueryableModel.Expression; }
}
public IQueryProvider Provider
{
get { return this.QueryableModel.Provider; }
}
public void Attach(TEntity entity)
{
this.ObjectSet.Attach(entity);
}
public void Detach(TEntity entity)
{
this.ObjectSet.Detach(entity);
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.QueryableModel.GetEnumerator();
}
}
Это очень просто и работает для простых запросов, например:
//db.Product is ObjectSetWrapper<Product>
var query = (from item in db.Product where item.Quantity > 0 select new { item.Id, item.Name, item.Value });
var itensList = query.Take(10).ToList();
Но когда у меня есть такие подзапросы:
//db.Product is ObjectSetWrapper<Product>
var query = (from item in db.Product
select new
{
Id = item.Id,
Name = item.Name,
SalesQuantity = (from sale in db.Sale where sale.ProductId == item.Id select sale.Id).Count()
}).OrderByDescending(x => x.SalesQuantity);
var productsList = query.Take(10).ToList();
Я получаю NotSupportedException, говоря, что я не могу создать постоянное значение моего внутреннего типа сущности запроса:
Невозможно создать постоянное значение типа "MyNamespace.Model.Sale". В этом случае поддерживаются только примитивные типы или типы перечислений. контекст.
Как я могу заставить мои запросы работать? Мне действительно не нужно, чтобы моя обертка была тип ObjectSet, мне просто нужно использовать ее в запросах.
Обновление
Я изменил свою подпись класса. Теперь он также реализует IObjectSet < > , но я получаю то же NotSupportedException:
public class ObjectSetWrapper<TEntity> : IQueryable<TEntity>, IObjectSet<TEntity> where TEntity : EntityObject