首页 新闻 会员 周边

Entity Framework 使用的问题

0
悬赏园豆:50 [已解决问题] 解决于 2014-09-25 20:33

就具体的问题来说吧

假设有一下三个表:

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语句或者存储过程的方法就不用说了。

 

 

 

 

问题补充:

上面的语句 可能有点问题,手工在这里输入的。细节就别太在意了。。。呵呵

算了的主页 算了 | 初学一级 | 园豆:3
提问于:2014-09-24 21:09
< >
分享
最佳答案
0

用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

             ......

          }

收获园豆:30
519740105 | 大侠五级 |园豆:5810 | 2014-09-25 08:41

我很想知道最终生成的sql是啥?

幻天芒 | 园豆:37175 (高人七级) | 2014-09-25 11:06

@幻天芒: 这个可以试试看。

最终的SQL里,会有:

left join

isnull 函数

519740105 | 园豆:5810 (大侠五级) | 2014-09-25 11:15

@519740105: 对复杂查询,总觉得用EF不太爽。

幻天芒 | 园豆:37175 (高人七级) | 2014-09-25 11:47

@幻天芒: 有所得就有所失,这个是没办法的。

直接用SQL自然性能高,但是呢?失去了ORM的便利、快捷与安全。

对于特别复杂的查询,可以考虑使用存储过程或使用视图来达成目的的。

519740105 | 园豆:5810 (大侠五级) | 2014-09-25 11:57

@519740105: 我觉得将功能分开组合,提供单表的整体ORM功能,然后提供复杂查询的对象映射。这样的orm就很霸道了~

幻天芒 | 园豆:37175 (高人七级) | 2014-09-25 12:12

@幻天芒: 期待HTM_ORM

519740105 | 园豆:5810 (大侠五级) | 2014-09-25 12:18

@519740105: ...把Linq+ibatis(dapper)等组合下就可以了~

EF的动态查询也有这样的效果,只是我觉得还需要一个SqlStatementManager来统一管理复杂的sql语句。

幻天芒 | 园豆:37175 (高人七级) | 2014-09-25 12:31

@519740105: 使用left join 查询,哎 我怎么就没想到呢。。呵呵

提供了一种思路呢。谢谢了

另外提,对于问题中的情况【但抛开不用sql和存储过程的限制】,如果是你的话,你会使用何种方式呢?

算了 | 园豆:3 (初学一级) | 2014-09-25 12:39

@算了: 我给你的方案里解决了这个问题,一般而言,我会选择这个方式,因为还是一段脚本达成目的,而不象你的代码,需要几段脚本,可读性相对来说差点。

当然,如果真的对性能影响很大时,可能会通过存储过程、视图甚至使用中间表的方式解决,但从你的这个需求而言是没必要的,最多也就是EF生成的SQL性能会有所降低(其实这个降低也可以忽略的)

519740105 | 园豆:5810 (大侠五级) | 2014-09-25 12:44

@幻天芒: 看到您的回复信息了

【我觉得将功能分开组合,提供单表的整体ORM功能,然后提供复杂查询的对象映射。这样的orm就很霸道了~】

这个我是个新手,所有看的似懂非懂,所以想确认一些想法。

您说的 "单表整体的ORM功能",是指对于单个数据库表 增删改查的功能么?

还有“提供复杂查询的对象映射”,这个怎么理解?是说像EF (Model First 还是 DbFirst 我忘记了)那样提供对 数据库 存储过程的映射么?(以前看过但是没有继续学习,貌似是 可以将存储过程,映射为C#里的方法,通过方法调用),我这样理解对么?

虽然我看到您是回复其他人的信息,但是很想知道,自己理解的对不对,菜鸟一枚,望百忙之余,能帮忙解答下心中的疑惑,先谢谢了。

算了 | 园豆:3 (初学一级) | 2014-09-25 12:45
其他回答(1)
0

单表整体的ORM功能=>我说的就是你所理解的那样,直接Add(实体)这种。不关心sql。

提供复杂查询的对象映射=>这个的话,我指的是由于查询是多变的,往往自动生成的sql代码不够优化,所以我只希望orm给我提供将查询的列映射到一个Model(属性和列名相同,或者依照一定的规则映射)或者List<Model>上的功能。

对于EF中将存储过程映射为方法,还是有很大的局限性。

看看ibatis.net,dapper等就可以知道他们提供的重要是对象映射和安全性(SQL注入)这块的功能。

收获园豆:20
幻天芒 | 园豆:37175 (高人七级) | 2014-09-25 12:51
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册