我使用了的DbContext接口,所以我可以写单元测试,我的服务层出这取决于具体的DbContext。这似乎并没有很好地工作,当有子查询中的LINQ语句。
I am using an interface for DbContext so that I can write unit tests for my Service Layer with out depending on concrete DbContext. This doesn't seem to work well when there are sub-queries in LINQ statements.
下面是一个简单的测试,我把测试EF5。
Here is a simple test that I put to test EF5 .
我宣布一个接口,用于我的数据库上下文
I declared an interface for my Db Context
public interface IDbContext
{
#region DbContext public properties
DbChangeTracker ChangeTracker { get; }
DbContextConfiguration Configuration { get; }
Database Database { get; }
#endregion
#region DbContext public methods
IEnumerable<DbEntityValidationResult> GetValidationErrors();
DbEntityEntry Entry(object entity);
DbEntityEntry<TEntity> Entry<TEntity>(TEntity entity) where TEntity : class;
DbSet<TEntity> Set<TEntity>() where TEntity : class;
DbSet Set(Type entityType);
int SaveChanges();
#endregion
}
public interface ISchoolContext : IDbContext,IDisposable
{
DbSet<Course> Courses { get; set; }
DbSet<Department> Departments { get; set; }
}
然后我SchoolEntities实现上述接口
And then my SchoolEntities implements the above interface
public partial class SchoolEntities : DbContext, ISchoolContext
下面code抛出一个错误System.NotSupportedException:无法创建类型的常量值'TestEF.Course只有基本类型或枚举类型,在这方面的支持。
The below code throws an error "System.NotSupportedException: Unable to create a constant value of type 'TestEF.Course'. Only primitive types or enumeration types are supported in this context".
*ISchoolContext* ctx = new SchoolEntities()
var query = from dep in ctx.Departments where dep.Budget > 0 && !ctx.Courses.Any(c => c.DepartmentID == dep.DepartmentID) select dep.DepartmentID;
以上code工作正常,如果我取代ISchoolContext声明与SchoolEntities。
The above code works fine if I replace ISchoolContext declaration with SchoolEntities.
SchoolEntities ctx = new SchoolEntities()
注:另外,code正常工作,在EF6接口。这是否意味着这是EF5一个错误?如果这是一个错误是没有任何黑客攻击吗?
Note: Also the code works fine with interface in EF6. Does this mean that this is a bug in EF5? If it is a bug is there any hack for this?
感谢您阅读长的帖子。
您遇到一个非常怪异的行为。你可以试试这个查询与你的榜样?它应该等于你的,但使用的是左连接。
You are encountering a very weird behavior. Could you try this query with your example ? It should be equal to yours but using a left join.
var query = from dep in ctx.Departments
join course in ctx.Courses
on dep.DepartmentID equals course.DepartmentID into leftJoin
from courseLeftJoin in leftJoin.DefaultIfEmpty()
where dep.Budget > 0 && courseLeftJoin == null
select dep.DepartmentID;
让我知道,如果它的工作原理与接口。
Let me know if it works with the interface.
编辑:
很高兴听到这个查询工作。我无法与EF5重现该问题。你能重新安装EF5 5.0.0?
Good to hear this query works. I wasn't able to reproduce the issue with EF5. Could you reinstall EF5 5.0.0 ?
对于这一点,请打开包管理器控制台(在菜单工具可用>的NuGet包管理器)来运行这个命令:
For that, please open a Package Manager Console (available in the menu Tools > NuGet Packet Manager) to run this command:
PM>安装,包装的EntityFramework -Version 5.0.0
PM> Install-Package EntityFramework -Version 5.0.0
这上面的线可以在的NuGet的官方网站。
EDIT2:
测试你的code之后,我能够重现问题。我看到了异常被抛出时System.Data.Objects.ELinq.Ex$p$pssionConverter.ConstantTranslator.TypedTranslate(Ex$p$pssionConverter父母,ConstantEx pression LINQ)。使用反编译器,我能够找到抛出行 NotSupportedException异常
。
After testing your code, I was able to reproduce the issue. I saw the exception was thrown at System.Data.Objects.ELinq.ExpressionConverter.ConstantTranslator.TypedTranslate(ExpressionConverter parent, ConstantExpression linq)
. Using a decompiler, I was able to find the line that throws the NotSupportedException
.
然后,我比较此功能EF5和EF6。下面是结果:
Then, I compared this function with EF5 and EF6. Here is the result: .
我不能说为什么这个错误发生,但我怀疑EF5的实现还不能处理你的情况,很遗憾。
I'm unable to say why this error occurs, but I suspect the implementation of EF5 doesn't handle your case, unfortunately.
我想你的code与code-第一的方针,并取得了成功。这个问题必须进行相关的设计方法(EDMX)。
I tried your code with the code-first approach and it succeeded. This issue must be related to the designer approach (EDMX).