代码如下:
var query = from g in _goodsInfoRepository.Table join s in _shopInfoRepository.Table on
new { id = g.ProviderInfo.ReferenceId, type = g.ProviderInfo.ReferenceType }
equals
new { id = s.ReferenceId, type = s.ReferenceType } into ps from r in ps.DefaultIfEmpty(null) where g.Id == goodsId && g.ProviderInfo.ReferenceId != null group new { g, r } by g.ProviderInfo into result select new { p = result.Key.Name, ss = result.Select(x => x.r).ToList() };
1、goods有属性ProviderInfo,一个goods有且只有一个ProviderInfo
2、ProviderInfo只是一个客户信息的外在表现形式,其本质是用户实体(比如PersonalInfo、CorporationInfo),通过ReferenceId和ReferenceType两个数据来指明具体的对象
3、ShopInfo是客户的店铺实体,同样的,通过ReferenceId和ReferenceType来识别ShopInfo的归属(PersonalInfo或CorporationInfo)
4、一个客户(PersonalInfo或CorporationInfo)可能有0个或多个ShopInfo。
目标:根据goodsId,按供ProviderInfo(ProviderInfo.Name)分组列表供应商对应的所有ShopInfo数据。当目标供应商不存在店铺信息时使用空对象(左关联)
转换成简单的SQL查询就是:
SELECT GoodsInfo.Name AS GoodsName, ProviderInfo.Name AS ProviderName, ShopInfo.Name AS ShopName FROM GoodsInfo INNER JOIN ProviderInfo ON GoodsInfo.ProviderId = ProviderInfo.Id LEFT OUTER JOIN ShopInfo ON ProviderInfo.ReferenceId = ShopInfo.ReferenceId AND ProviderInfo.ReferenceType = ShopInfo.ReferenceType WHERE (GoodsInfo.Id = '2b2b8fe9-73ae-e411-8154-5404a6f3ab2f')
问题:
明明有ShopInfo的信息,但结果里的ShopInfo是空(结果集合有一个空对象的元素)。
确实够复杂的,我一整个项目里面也没有一两个这样的语句。
通常用视图+存储过程全部解决在数据库端,前端把视图和存储过程返回结果当Table操作。
如果用Linq,我可以通过Include的方式把ShopInfo配置的图片配置信息(logo)也带出来,一次sql访问查询。
现在我是:
1、查询GoodsInfo,include ProviderInfo以获取ProviderInfo的Name
2、调用存储过程执行上面写的sql代码获取shopinfo
3、问题是:如果我的shopinfo有很多(事实是这样),那需要用到shopinfo的logo时候,就会在EF中执行多次的查询。
监视Linq生成的语句长什么样~
太复杂了。看着就头痛,生成的SQL也是ShopInfo为空的。
现在暂时用直接执行SQL的方式达成目的。
@519740105: 那就是写法导致sql生成错误了嘛。。表示对于复杂sql,我一般不会靠自动生成。我喜欢的方式是对于单表直接orm,对于查询类那么直接原生sql。符合这样标准的orm还是很多滴。
@幻天芒: 目前先用Sql代替了。
@519740105: 简单,直接。