一个很奇怪的问题。
原先的项目是好好的,因为需要,增加了一些实体,也没什么改动,但就报告这个错误了。
项目是EF,参考代码如下:
class A { public int Id{get;set;} } class B { public int Id{get;set;} public int Aid{get;set;} public virtual A A{get;set;} } //下面的Linq就报告错误: Bs.Where(x=>x.A==a).FirstOrDefault();
编译错误还是运行时错误?我试了一下这几句代码,不会出现错误。编译不会,运行也不会。
运行错误。
类似代码,之前都好的,现在不知道是我数据库的问题,还是项目的问题,导致了这个问题的出现。
@519740105: 那这样没有办法了,你起码得抽象出可以重现问题的代码。
错误你也没有写完整,后面是这样的吗?
System.NotSupportedException
Unable to create a constant value of type 'System.Object'.
Only primitive types ('such as Int32, String, and Guid') are supported in this context.
@爱编程的大叔: 完整的错误如下:
Unable to create a constant value of type 'CrmOldNew.DDD.Entities.Employee'. Only primitive types or enumeration types are supported in this context.
替换为上面的模拟代码就是引号里的字符串变成 A
@519740105:
Bs.Where(x=>x.A==a).FirstOrDefault();
这句我一开始就觉得有问题啊。你确定a是一个对象,然后Class A支持Equals比较?
感觉这样对头一些
Bs.Where(x=>x.A.Id==a).FirstOrDefault();
补充,如果a是对象,你就
Bs.Where(x=>x.A.Id==a.Id).FirstOrDefault();
@爱编程的大叔: 当然确定a是一个对象,就是前面示例的,a就是类型A的实例对象。
你这条语句:Bs.Where(x=>x.A==a).FirstOrDefault() ,是不是可以这样写:
A a = new A;
dbContext.DbSet<B>.Where(x=>x.A == a).FirstOrDefault();
不是。
a本身是从A里查询出来的。
类似于:
var a = As.FirstOrDefault();
Bs.Where(x=>x.A==a).FirstOrDefault();
@519740105: 改成这样:Bs.Where(x=>x.A.Id==a.Id).FirstOrDefault() 是不是就正确了?
@Launcher: 对。写成 x=>x.Aid == a.Id 也可以通过。
问题是:
这样写有很多麻烦,而且之前很多代码都是用的 x.A==a 。
再者,作为技术问题,这个问题是怎么导致的,该如何解决,才是关键。
@519740105: 应该是无法编译成 SQL 语句的问题。
@519740105: LINQ不知道如何翻译。对象不可翻译。
@Launcher: 错误意思是这样的。
但是:这个语句之前是OK的,现在却突然不行了,这个才是问题的关键。
@519740105: 如果能确认之前是可以的,现在却不行了。
很可能的一个情况的,你们有人之前改写了表达式解析器,让LINQ支持此类对象EQUALS的表达式解析,
然后由于some reason,没有引人相应解析器的命名空间或是引用DLL,或是此DLL不小心被人覆盖为旧版本。
我使用的system.data.linq.dynamic中间关于GUID的比较器代码也是错的,需要自行修改后才能正常使用。(我大量使用了GUID当Primary Key)
另外还使用linqKit实现了linq的where(filterString)扩展,这些不引用的时候,表现出来的错误也是很离奇的。
@爱编程的大叔: OK,我研究下。
另外,你用Guid当主键,能介绍下吗?我有这个计划,还没最终确定。
@519740105: 加你QQ,不过比较奇怪你是湖南人,在广州?可是你一直说自己在合肥?
@爱编程的大叔: 68558710。
籍贯湖南郴州,户籍广东韶关,一直在广州,去年到上海,又转合肥。
这个错误似乎和上面代码没什么关系,应该是说Type类型不能用于常量吧