Linq多表查询 返回组合实体 踩坑记

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linq多表查询 返回组合实体 踩坑记相关的知识,希望对你有一定的参考价值。

新年就不再记流水账了吧,无关紧要的日志太多也不好,有时要找自已记录的一些要点要翻半天

春节假期在家陆陆续续也有在做公司的事,主要是重构,接手的代码看着比较乱,花了很多时间来重构,现在看上去好多了。

使用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 (IEnumerable<object>)Model)
{
    var name = item.GetType().GetProperty("Name").GetValue(item, null);
}

这样就能取的到了。虽然用了反射性能会差些,但总算是能实现了。再把这行封装下,看上去就和普通类一样用了。

 

以上是关于Linq多表查询 返回组合实体 踩坑记的主要内容,如果未能解决你的问题,请参考以下文章

记一次 Spring 事务配置踩坑记

linq多表查询怎么用List<T>返回?

c# ef框架怎么使用linq语句多表查询?

遍历forEach与map的区别-forEach踩坑记

Abp vnext EFCore 实现动态上下文DbSet踩坑记

MongoDB多表关联分组查询指定行数数据实践遇坑记及解析