最近在学习使用ef框架,在使用过程中遇到一个问题,问题描述如下:
由于使用Codefirst,数据库的创建是根据实体属性来的。有些属性不需要创建对应的表字段。ef中可以使用NotMapped来标识类的某个属性不需要创建对应的数据库字段。
但是此操作会导致在调用ef中执行sql脚本函数(context.database.sqlquery)的时候,被NotMapped描述属性不能被正常查出来。
例如:
class a 中有属性 fieldA,fieldB,fieldC。fieldC有NotMapped描述。
执行List<a> result = context.database.sqlquery<a>("select fieldA,fieldB,1 as filedC").tolist();
查询结果result中的fieldC的属性为null。
解决方案:
使用viewmodel的形式获取数据,然后将数据拷贝到a中。
class b:a{}
b不包含在ef上下文中。
List<a> result = context.database.sqlquery<b>("select fieldA,fieldB,1 as filedC").select(x=>new a(){
fieldA=x.fieldA,
fieldB=x.fieldB,
fieldC=x.fieldC
}).tolist();
这种方式可以解决问题,但是总觉得多绕了一步。监测数据库的时候看到ef发送的sql指令是完完整整发过去的。也就是说ef肯定是接收到了一张完整,包含fieldC字段的一张表的。只是在将表转化成对象的时候忽略掉了这个字段。我却因为这个要去新建一个“无意义”的实体。觉得有些别扭,网上没找到想要的答案。所以在发在园子里求大佬赐教。
经过测试,使用导航属性也可以做联表查询。效果如图
不过此种方式应该和用linq最终干的事情一致。将表达式/linq转成sql语句。比较复杂的查询速度可能就比较慢。貌似ef就这3种解决方案了。如果后面真的效率很差,考虑接下来的开发里可能自己封装一个执行sql的方法。
1. 你可以不必建这个属性的。
2. 如果你非要有这个属性, NotMapped 的属性,你又非要从数据库查询中取,当然是这个鬼样了。
人家提供了让你可以有属性不映射到数据库,没说让你从数据库取值的,
比如像你这样的,完全可以在构造函数中直接给 fieldC赋值的。
谢谢你的建议。
filedC实际来源其实联表查询中另一张表的字段。所以构造函数应该是行不通的。
我之所以“非要”用NotMapped,又希望ef在查询的时候能帮我查出来,是因为觉得ef应该有办法可以直接把filedC转换到NotMapped的实体中。我觉得这个操作并不会影响到ef的其他操作。我把sqlquery想象成利用反射将table中的数据赋值到类中,然后ef在这个过程中判断了NotMapped 。如果我想的没错的话。那不判断NotMapped也不会造成啥负面影响。然后自己最终结论就是:是不是有啥ef配置是我不知道的。所以没有达到我预期的效果。
@Kevin_Ni: 是这样的,你觉得的不一定对,当然你可以想办法证明你对。
然后去找微软那群渣程序员,让他们实现这个对的功能。
要不然呢,横向多学点其他的编程知识,理解一下微软的程序员要面对一群各种不同想法都认为自己很对很好的,然后需求又是冲突的时候,他们需要做的选择。
当然,还有一个方法,等个十年八年的,说不定微软的渣程序员突然开悟了呢。
因为你举例是那样的,所以回答自然是构造函数,如果你举例包含join 表了,自然也有其他的解决方案,当然非要撞死在南墙上也是没有办法的。
@爱编程的大叔: 感谢你的回答,就是因为对“自己的理解”保留怀疑态度。所以发出此问题寻找更多的见解。
请问你指的其他的解决方案是啥?能详细说明吗?
我先说明下我另外两种对于处理这个问题上有缺陷的解决方案:
一、使用导航属性
二、使用from c in context.tablea join tableb
方案一的缺陷,查询的时候不能对导航属性做筛选
方案二的缺陷,可以对join的表做筛选,但是复杂的联表查询ef转化成sql的时候效率相对较低
恳请赐教
@Kevin_Ni: 赐教谈不上。
首先,实际上我是不知道你的需求是啥的,你一上来直奔的就是notmapped属性,而不是说明你的需求。
其次,谁说导航属性不能筛选来着?我前两天还在筛选呢,难道数据在骗我,还是EF升级以后突然就没这功能了。
再次,效率只有必要的时候才是有用的,无用的效率无需关心,需要关心效率的你就不会写复杂的联表查询了。
最后,本来就没有一种能满足所有需求的软件,你不要把所有的希望全寄托在EF身上。
@爱编程的大叔: 可能我表达能力不是很好。所以我问问题一般一步步的抛问题。怕一次全抛出来写的太乱别人看不懂。效率问题确实如你所说,在没有出现效率问题的时候去过分研究效率问题反而耽搁了其他事情的推进。再次感谢你的回答。我先去查看下导航属性相关的文档。感谢。