.net – 实体框架4.1中的接口和存储库抽象中断子查询DbContext API?

目标:
我试图使用新的Entity Framework 4.1 DbContext API(使用数据库优先与新的ADO.NET DbContext生成器进行POCO类),并使用基本的通用存储库提供一层抽象.

问题:
如果我尝试在我的存储库中使用子查询,EF无法完成翻译并发出错误:
System.NotSupportedException:LINQ to Entities不能识别方法’System.Linq.IQueryable`1 [EntityFramework41Test.Data.Entity.Table2] Query()’方法,而且这种方法不能转换为存储表达式.

过去我已经成功地使用了旧的4.0 ObjectContext设计,但是我想使用新的API.同样的方法也与4.0 ObjectContext API(使用生成的POCO实体进行测试)失败.

注意:我不认为发布数百行代码是现实的,但是我有一个使用SQL Server CE 4.0的ASP.NET MVC 3项目的示例解决方案,以及一个基本的单元测试项目,展示了可以使用的各种方法的结果如果有帮助,上传或发送电子邮件.

我使用的存储库界面是简单的:

public interface IRepository<TEntity> : IDisposable where TEntity : class,ITestEntity
{
    TEntity GetById(int id);
    IQueryable<TEntity> Query();
    void Add(TEntity entity);
    void Remove(TEntity entity);
    void Attach(TEntity entity);
}

上下文界面更简单:

public interface ITestDbContext : IDisposable
{
    IDbSet<TEntity> Set<TEntity>() where T: class,ITestEntity;
    void Commit();
}

以下是使用存储库和上下文实例的接口的示例用法:

using (ITestDbContext context = new TestDbContext())
using (IRepository<Table1> table1Repository = new Repository<Table1>(context))
using (IRepository<Table2> table2Repository = new Repository<Table2>(context))
{
    // throws a NotSupportedException
    var results = table1Repository.Query()
        .Select(t1 => new
        {
            T1 = t1,HasMatches = table2Repository.Query()
                .Any(t2 => t2.Table1Id == t1.Id)
        })
        .ToList();
}

上面的代码是我想使用的方法.具体课程最终会被注入.

请不要使用比使用子查询更好的方法来编写这个特定的查询.我有意地简化了代码,专注于实际问题:EF不会翻译查询.

存储“内部”存储库Query()方法导致一个局部变量实际上是有效的,但并不理想,因为你必须记住这样做.

using (ITestDbContext context = new TestDbContext())
using (IRepository<Table1> table1Repository = new Repository<Table1>(context))
using (IRepository<Table2> table2Repository = new Repository<Table2>(context))
{
    var table2RepositoryQuery = table2Repository.Query();

    // this time,it works!
    var results = table1Repository.Query()
        .Select(t1 => new
        {
            T1 = t1,HasMatches = table2RepositoryQuery
                .Any(t2 => t2.Table1Id == t1.Id)
        })
        .ToList();
}

我也注意到其他一些方法破裂或成功,例如不考虑存储库并调用TestDbContext.Set< TEntity>()工作,但ITestDbContext.Set< TEntity>()将不会转换.更改ITestDbContext.Set< TEntity>()的定义以返回DbSet< TEntity>而不是IDbSet< TEntity>仍然失败

编辑:
我不认为这是可能的,没有一些查询拦截和翻译.如果我将来找到一个解决方案,我一定会分享一下.

解决方法

我没有EF的经验,但是基于使用NHibernate及其不断发展的LINQ支持,我怀疑你的问题的答案是你不会喜欢的 – 听起来这个特定的结构不是(但是? )由EF LINQ提供商支持,您需要更改查询.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


c语言数组越界会怎么样
c语言指针怎么等于数组
c语言数组怎么存入文字
c语言中怎么显示数组
c语言数组元素怎么选
c语言数组怎么累加
c语言数组符号怎么输入
c语言怎么用长数组
c语言数组函数怎么输入
c语言数组怎么去掉差异
c语言怎么求解数组
c语言数组怎么用变量
c语言怎么申明数组
c语言怎么控制数组
c语言怎么计算数组长度
c语言数组怎么插星号
c语言数组怎么加长度
c语言中怎么输出数组
c语言怎么记住数组边界
c语言数组怎么输入符号