【发布时间】:2026-02-11 14:45:01
【问题描述】:
为了在密集的数据库使用系统中进行访问控制,我必须实现一个对象集包装器,在其中检查 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
【问题讨论】:
-
最喜欢的问题是你的
ObjectSetWrapper是不是ObjectSet。您可以考虑使用 EF6 的DbSet执行此操作,您可以继承和覆盖其中的方法。 -
我也试过 @GertArnold ,我现在实现了 ObjectSet 和 IQueryable,但错误仍然存在。
-
我不禁想知道您为什么要明确地使用 EF 进行联接。与协会相反。我很确定 EF 会尝试使用
CROSS APPLY,因此无法通过...尝试用SalesQuantity = item.Sales.Count()替换该行来执行此命令
标签: c# linq entity-framework-4 wrapper iqueryable