使用通用谓词的实体框架

发布于 2024-08-14 08:25:49 字数 895 浏览 1 评论 0原文

我使用 DTO 通过存储库模式在业务层和实体框架层之间进行映射。

标准调用看起来像

public IClassDTO Fetch(Guid id)
{
    var query = from s in _db.Base.OfType<Class>()
        where s.ID == id
        select s;

    return query.First();
}

现在我希望从业务层传递过滤条件,所以我尝试了

public IEnumerable<IClassDTO> FetchAll(ISpecification<IClassDTO> whereclause)
{            
    var query = _db.Base.OfType<Class>()
        .AsExpandable()
        .Where(whereclause.EvalPredicate);      

    return query.ToList().Cast<IClassDTO>(); 
}

来自业务层的调用将类似于

Specification<IClassDTO> school =
    new Specification<IClassDTO>(s => s.School.ID == _schoolGuid);

IEnumerable<IClassDTO> testclasses = _db.FetchAll(school);

我遇到的问题是无法从 EF 查询中推断出 .Where 子句的用法。如果我在表达式中使用具体类型,那么它可以找到,但我不想将我的业务层直接暴露给 EF。

I use DTO's to map between my Business and Entity Framework layer via the Repository Pattern.

A Standard call would look like

public IClassDTO Fetch(Guid id)
{
    var query = from s in _db.Base.OfType<Class>()
        where s.ID == id
        select s;

    return query.First();
}

Now I wish to pass in filtering criteria from the business layer so I tried

public IEnumerable<IClassDTO> FetchAll(ISpecification<IClassDTO> whereclause)
{            
    var query = _db.Base.OfType<Class>()
        .AsExpandable()
        .Where(whereclause.EvalPredicate);      

    return query.ToList().Cast<IClassDTO>(); 
}

The Call from the business layer would be something like

Specification<IClassDTO> school =
    new Specification<IClassDTO>(s => s.School.ID == _schoolGuid);

IEnumerable<IClassDTO> testclasses = _db.FetchAll(school);

The problem I am having is that the .Where clause on the EF query cannot be inferred from the usage. If I use concrete types in the Expression then it works find but I do not want to expose my business layer to EF directly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦纸 2024-08-21 08:25:49

尝试将 FetchAll 改为类上的泛型,如下所示:-

public IEnumerable<T> FetchAll<T> (Expression<Func<T,bool>> wherePredicate)
  where T:IClassDTO  //not actually needed
{            
    var query = _db.Base.OfType<T>()
        .AsExpandable()
        .Where(wherePredicate);      

    return query; 
}

改为传入 school.Evalpredicate。 FetchAll 似乎不需要了解整个规范,它只需要谓词,对吧?如果您需要将其转换为 IClassDTO,请在列表中获得结果后执行此操作。

Try making FetchAll into a generic on a class instead, like this:-

public IEnumerable<T> FetchAll<T> (Expression<Func<T,bool>> wherePredicate)
  where T:IClassDTO  //not actually needed
{            
    var query = _db.Base.OfType<T>()
        .AsExpandable()
        .Where(wherePredicate);      

    return query; 
}

pass in school.Evalpredicate instead. FetchAll doesn't appear to need to know about the whole specification, it just needs the predicate, right? If you need to cast it to IClassDTO, do that after you have the results in a List.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文