首页新闻找找看学习计划

linq to entites 写查询语句 如何像 sql 文那样拼串

0
悬赏园豆:100 [待解决问题]

我在网上看了一些文章,对于一些简单的linq 可以用expression来拼 ,但是仍然不知道复杂的如何来拼,难道真需要用那种极其复杂的繁琐的表达式树,一点点的拼起来吗?那不是噩梦么?

如下: from tohos in
orgCancel(start, end)
group tohos by new { tohos.RESERVE_TIME.Year, Half = (tohos.RESERVE_TIME.Month - 1) / 6 }
into gs
select new
{
gs.Key,
Group = gs.GroupBy(c => new
{
c.RESERVE_TIME.Year,
c.RESERVE_TIME.Month,
c.RESERVE_TIME.Day
}
).Select(d => new
{
d.Key,
Count = denoReservePatientCount(start, end, d.Key.Year, d.Key.Month, d.Key.Day, d.Count())
})
}

protected double denoReservePatientCount(DateTime start, DateTime end, int Year, int Month, int Day, int num)
{
return num == 0 ? 0 : 100d * (double)num /
denoReservePatient(start, end).Where(c => c.RESERVE_TIME.Year == Year && Month == c.RESERVE_TIME.Month && Day == c.RESERVE_TIME.Day
).Count();
}

protected IQueryable<ReserveSex> denoReservePatient(DateTime start, DateTime end)
        {
            var q = from r in _analysisEntity.RESERVE_TBL
                    join p in _analysisEntity.PATIENT_TBL on r.RS_PATIENT_ID equals
                    p.PB_PATIENT_ID
                    where r.RESERVE_TIME >= start && r.RESERVE_TIME < end && p.BIRTHDAY != null
                    select new ReserveSex { CONTACT = r.CONTACT, NET_RESERVE = r.NET_RESERVE, RESERVE_TIME = r.RESERVE_TIME, RS_PATIENT_ID = r.RS_PATIENT_ID, PB_SEX_ID = p.PB_SEX_ID, BIRTHDAY=p.BIRTHDAY };

请教一下各位大大,denoReservePatientCount 这个方法其实在表达式树的解析中会出错,报说linq to entites 无法解析这个方法,但是我的sql统计中大量存在 比如denoReservePatientCount的方法,那我该怎么来拼接他呢?
万分感激~~

问题补充: 是这样,可能我上面那个问题说的很不清楚还有错误,其实IEnumerable不能作为表达式树解析的结构,IQueryable可以,一般简单的拼接,直接用Expression就可以用了。 但是复杂一点的,我就不清楚了,如下: from tohos in orgCancel(start, end) group tohos by new { tohos.RESERVE_TIME.Year, Half = (tohos.RESERVE_TIME.Month - 1) / 6 } into gs select new { gs.Key, Group = gs.GroupBy(c => new { c.RESERVE_TIME.Year, c.RESERVE_TIME.Month, c.RESERVE_TIME.Day } ).Select(d => new { d.Key, Count = denoReservePatientCount(start, end, d.Key.Year, d.Key.Month, d.Key.Day, d.Count()) }) } protected double denoReservePatientCount(DateTime start, DateTime end, int Year, int Month, int Day, int num) { return num == 0 ? 0 : 100d * (double)num / denoReservePatient(start, end).Where(c => c.RESERVE_TIME.Year == Year && Month == c.RESERVE_TIME.Month && Day == c.RESERVE_TIME.Day ).Count(); } denoReservePatientCount 这个方法其实在表达式树的解析中会出错,报说linq to entites 无法解析这个方法,但是我的sql统计中大量存在 比如denoReservePatientCount的方法,那我该怎么来拼接他呢? 望赐教
boool的主页 boool | 初学一级 | 园豆:20
提问于:2010-11-17 09:25
< >
分享
所有回答(1)
0

denoReservePatient方法在哪??返回的是什么类型?

斯克迪亚 | 园豆:4124 (老鸟四级) | 2010-11-17 16:59
我在帖子上把那个方法贴出来了,不过,不管这个方法返回啥类型,linq to entities都不能解析denoReservePatientCount,denoReservePatient 的类型,总是报错。斯大有什么好办法
支持(0) 反对(0) boool | 园豆:20 (初学一级) | 2010-11-17 17:06
哦,看到了,不过貌似里面没有return?? 你先返回值改为IEnumerable<ReserveSex>,然后return q.ToLsit()看看,如果运行没问题了,就尝试改回来,再这样写: if(num==0)return 0; var x=denoReservePatient(start, end).Where(c => c.RESERVE_TIME.Year == Year && Month == c.RESERVE_TIME.Month && Day == c.RESERVE_TIME.Day ).Count(); return 100d * (double)num /i; 我印象中只有在查询表达式中调用其它方法会报错,因为Linq无法将其它函数转换为SQL语句,而像这样的组合我自己没试过,理论上应该不成问题呃。 实在还不行的话就只有返回ToList()形式的列表再进行后续查询了,这样就会回归到Linq to object范畴,怎么查询都没问题了,而且鉴于你这里的功能而言,你已经通过新建对象创建了一个新的列表,这时候后续查询也都是针对这个新列表而非数据库的了,所以转换为ToList()形式理论上没有任何损失。
支持(0) 反对(0) 斯克迪亚 | 园豆:4124 (老鸟四级) | 2010-11-17 17:33
又猜想了一下,关于你这里说的: “不过,不管这个方法返回啥类型,linq to entities都不能解析” 你以前改为IEnumerable<ReserveSex>返回类型的时候,有执行过ToList()方法吗?如果没有的话,那它实际还是 IQueryable<ReserveSex> 类型,所以后续的操作应该还是在linq to entities范畴,而后续操作时都是针对ReserveSex 类型查询的,linq to entities不知道如何处理针对ReserveSex 类型的查询(因为最终都要转换为SQL语句,SQL里没有类这回事),所以才会报错吧。
支持(0) 反对(0) 斯克迪亚 | 园豆:4124 (老鸟四级) | 2010-11-17 17:46
呵呵,首先谢谢斯大的回复,是这样的,我希望是用IQueryable,原因您也说的很清楚了,其实就是想象一条sql语句那样执行,让数据库直接把结果返回,而不用把数据取到本地,然后再象linq to object那样在内存中筛选。 那个ReserveSex其实没有关系的,他只是存放了几个字段,会像sql语句那样取那几个字段回来的,我在More Effective C#中看到似乎IQueryable在解析成表达式树的时候有时候无法解析你写的方法,但是我发现基本上只要不是像上面的denoReservePatientCount在groupby的select里面的函数,像orgCancel(start, end) 之类的函数,IQueryable还是能解析的,所以我非常困惑为什么denoReservePatientCount就不能解析,尤其我非常想知道,如果我想复用denoReservePatientCount里的逻辑该怎样做??总不能让我把它里面的东西都拿出来写在每个linq里吧?
支持(0) 反对(0) boool | 园豆:20 (初学一级) | 2010-11-17 22:57
denoReservePatientCount就不能解析 关于这个我大概得到了一个结论类似select 和 where里面写的函数,SQLserver的IQueryableProvider是不能够解析的,所以,怎样复用denoReservePatientCount这个函数里面的内容,希望能得到指点!!~~
支持(0) 反对(0) boool | 园豆:20 (初学一级) | 2010-11-18 08:42
你试试new ReserveSex改为new 匿名类行不行呢?返类型改为IQueryable<object>
支持(0) 反对(0) 斯克迪亚 | 园豆:4124 (老鸟四级) | 2010-11-18 14:44
谢谢斯大的回复~ 匿名类型不能被转换成object的,我觉得本质问题是IQueryable的查询中,linq在生成表达式树的时候,它解析不了select和where之类操作内写的方法,或者说根本它不去解析,遇到有方法就直接扔异常了。我感觉是这样,呵呵,我就寻思,要是linq不能这样解析的话,是不是就只能用表达式树来拼写了?只是表达式树太麻烦了,需要定义的东西太多,而我的sql又比较长,拼起来太繁琐了,就没有什么稍微好点的办法吗??
支持(0) 反对(0) boool | 园豆:20 (初学一级) | 2010-11-18 14:56
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册