就具体的问题来说吧
假设有一下三个表:
PromoTable : PromoPrice
CustPriceTable : CustGoodsPrice
GoodsTable : GoodsPrice
有以上三张表,促销表,有商品的促销价格
客户表,有商品的客户要货价格
商品表,有商品的默认价格
【这里就不要考虑这样设计表 合理不合理了。简化而已。理解意思即可】
在做订单的时候,要在订单明细表中记录商品的订单价格
订单价格有这样的规则
如果商品当前有促销,则使用促销价格
如果商品没有促销,就取客户价格
如果商品没有客户价格,才取默认价格
如果用EF来做的话怎么做呢?
具体点说
假定在做新建订单的界面,需要根据商品ID显示出商品当前的订单价格
public OrderDetailDTO GetOrderDetail ( int goodsID ){
【取得商品的基本信息】
OrderDetailDTO OD = (from g in context.Goods
where g.goodsID == goodsID
select new OrderDetailDTO {
Name = g.Name,
Price = g.Price
......
}).FirstOrDefault();
float prise
try{
【取得促销价格】
OD.prise = (from p in context.PromoDetailTable
where p.goodsID == goodsID
select p.price).Single();
}catch{
【取得促销价格】
OD.prise= (from cg in context.CustPriceTable
where cg.goodsID == goodsID
select p.price).single();
}
return OD;
}
这是我自己想到的办法,
我就想知道,使用EF就这么做么?还是有更好的办法。
另外通过EF运行SQL语句或者存储过程的方法就不用说了。
上面的语句 可能有点问题,手工在这里输入的。细节就别太在意了。。。呵呵
用Left Join可以一条语句解决:
from g in context.Goods
join p in context.PromoDetailTable on g.goodsid equals p.goodsid into pg
join c in context.CustPriceTable on g.goodsid equals c.goodsid into cg
from pt from pg.DefaultIfEmpty()
from ct from cg.DefaultIfEmpty()
where g.goodsid==goodsid
select new OrderDetailDTO {
Name = g.Name,
Price = pt != null ? pt.price : ct != null ? ct.price : g.Price
......
}
我很想知道最终生成的sql是啥?
@幻天芒: 这个可以试试看。
最终的SQL里,会有:
left join
isnull 函数
@519740105: 对复杂查询,总觉得用EF不太爽。
@幻天芒: 有所得就有所失,这个是没办法的。
直接用SQL自然性能高,但是呢?失去了ORM的便利、快捷与安全。
对于特别复杂的查询,可以考虑使用存储过程或使用视图来达成目的的。
@519740105: 我觉得将功能分开组合,提供单表的整体ORM功能,然后提供复杂查询的对象映射。这样的orm就很霸道了~
@幻天芒: 期待HTM_ORM
@519740105: ...把Linq+ibatis(dapper)等组合下就可以了~
EF的动态查询也有这样的效果,只是我觉得还需要一个SqlStatementManager来统一管理复杂的sql语句。
@519740105: 使用left join 查询,哎 我怎么就没想到呢。。呵呵
提供了一种思路呢。谢谢了
另外提,对于问题中的情况【但抛开不用sql和存储过程的限制】,如果是你的话,你会使用何种方式呢?
@算了: 我给你的方案里解决了这个问题,一般而言,我会选择这个方式,因为还是一段脚本达成目的,而不象你的代码,需要几段脚本,可读性相对来说差点。
当然,如果真的对性能影响很大时,可能会通过存储过程、视图甚至使用中间表的方式解决,但从你的这个需求而言是没必要的,最多也就是EF生成的SQL性能会有所降低(其实这个降低也可以忽略的)
@幻天芒: 看到您的回复信息了
【我觉得将功能分开组合,提供单表的整体ORM功能,然后提供复杂查询的对象映射。这样的orm就很霸道了~】
这个我是个新手,所有看的似懂非懂,所以想确认一些想法。
您说的 "单表整体的ORM功能",是指对于单个数据库表 增删改查的功能么?
还有“提供复杂查询的对象映射”,这个怎么理解?是说像EF (Model First 还是 DbFirst 我忘记了)那样提供对 数据库 存储过程的映射么?(以前看过但是没有继续学习,貌似是 可以将存储过程,映射为C#里的方法,通过方法调用),我这样理解对么?
虽然我看到您是回复其他人的信息,但是很想知道,自己理解的对不对,菜鸟一枚,望百忙之余,能帮忙解答下心中的疑惑,先谢谢了。
单表整体的ORM功能=>我说的就是你所理解的那样,直接Add(实体)这种。不关心sql。
提供复杂查询的对象映射=>这个的话,我指的是由于查询是多变的,往往自动生成的sql代码不够优化,所以我只希望orm给我提供将查询的列映射到一个Model(属性和列名相同,或者依照一定的规则映射)或者List<Model>上的功能。
对于EF中将存储过程映射为方法,还是有很大的局限性。
看看ibatis.net,dapper等就可以知道他们提供的重要是对象映射和安全性(SQL注入)这块的功能。