新年就不再记流水账了吧,无关紧要的日志太多也不好,有时要找自已记录的一些要点要翻半天
春节假期在家陆陆续续也有在做公司的事,主要是重构,接手的代码看着比较乱,花了很多时间来重构,现在看上去好多了。
使用Linq进行多表查询,要返回各个表的几个组合数据,
public class A{ public string NameA{get; set;} } public class B{ public string NameB{get; set;} }
1、原先项目是定义了一个类,里面包含几张表的各个字段。这样效率是比较高,就是要特别为这个查询定义一个类很讨厌。如果数据库字段有变化,还要手动修改这个类。而且如果有各种组合的查询,岂不是要定义很多个这样的类。。。实际上,公司原先项目就是定义了很多类,来应付各种查询。
public class C{ public string NameA{get;set;} public string NameB{get;set;} }
2、我想,A和B里都定义好了,直接包含这两个类不就行了吗?
public class C{ public class A{get;set;} public class B{get;set;} }
from x in xx join y in YY on ....... select new C{ A = { NameA=x.Name }, B = { NameB=y.Name } }
写的时候智能提示妥妥的,感觉都能用。今天测试时发现,报linq无法XXX复杂实体XXX之类的错。
3、如果是返回数据以一张表为主,可以定义个类,继承主表的实体,再另外加其它表的字段。(如果继承的是EF的,要在类前加上[NotMapped]来取消映射)
具体没有尝试过,但我在其它地方有这样使用过是可以。可以减少一部份工作,但其它字段还是要手动添加。而且如果是几张表各取几个字段,这样用也不合适。
4、匿名类
from x in xx join y in YY on ....... select new { NameA=x.Name, NameB=y.Name }
匿名类实际上也是一个正常的类,只不过编译器帮我们定义好了。但要取数据时杯具了,明明下了断点能看到值,就是取不出来。
4.1、assembly:InternalsVisibleTo
搜索了下,是因为匿名类是Internal,不能跨程序集(试了一下,在DAL刚返回时是能取到值的,到控制器和UI那边就取不出来了,item.Name会报 object不存在xx属性 之类的错,但下断点明明可以看到值)
要在AssemblyInfo中增加assembly:InternalsVisibleTo("对方程序集名"),但我试了还是不行,而且这个功能是要给其它地方引用的,这样解决也不合适。
4.2 dynamic
原先用object,改成dynamic还是一样,但搜了一下,稍改进一下就可以了。
@foreach (var item in Model) { var name = item.GetType().GetProperty("Name").GetValue(item, null); }
这样就能取的到了。虽然用了反射性能会差些,但总算是能实现了。再把这行封装下,看上去就和普通类一样用了。