首页
视频
资源
登录
DJ王重阳
慢慢来
博主信息
排名
6
文章
6
粉丝
16
评论
8
文章类别
ORM_EF
3篇
.NET Core
2篇
最新文章
最新评价
{{item.articleTitle}}
{{item.blogName}}
:
{{item.content}}
关于我们
ICP备案 :
渝ICP备18016597号-1
网站信息:
2018-2024
TNBLOG.NET
技术交流:
群号656732739
联系我们:
contact@tnblog.net
欢迎加群
欢迎加群交流技术
原
.NET实现ORM-EF的Lambda查询一对多转一对一,即实现List<T>.SelectMany()方法,并对其进行为空处理
6599
人阅读
2021/3/25 20:29
总访问:
24071
评论:
1
收藏:
1
手机
分类:
ORM_EF
#### 我们借助微软官方方法参数进行修改实现命名方法为MySelectMAny: public static IEnumerable<TResult> MySelectMAny<TSource, TCollection, TResult>(this IEnumerable<TSource> source, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector); ####泛型参数理解: TSource:数据源泛型 TCollection:解析字段后的泛型 TResult:返回值泛型 #### 实现步骤(利用嵌套foreach()和传入委托进行循环遍历): 1.预先创建一个返回值对象集合 ```csharp List<TResult> listTResult = new List<TResult>(); ``` 2.利用foreach()循环遍历数据源 ```csharp foreach (TSource itemMany in source){} ``` 3.利用foreach()和collectionSelector()委托嵌于上一个循环中,循环遍历需要解析的字段(即本文itemMany) ```csharp foreach (TCollection itemone in collectionSelector(itemMany)){} ``` 4.通过判断解析后获得的值,进行返回值对象的创建、赋值和是否需要添加至返回值对象集合中 ```c if(itemtwo!=null){ //创建一个返回对象 TResult tResult=default(TResult); //利用resultSelector()委托,将返回值赋给返回对象 tResult = resultSelector(itemMany, itemone); //将返回值对象添加到返回值对象集合中 listTResult.Add(tResult); } ``` 5.最后返回对象集合 ##具体代码: ```csharp //拓展方法创建 public static class SelectManyExtands { public static IEnumerable<TResult> MySelectMany<TSource, TCollection, TResult>(this IEnumerable<TSource> source, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource,TCollection, TResult> resultSelector) { //创建一个返回值对象集合 List<TResult> listTResult = new List<TResult>(); //利用foreach()循环遍历数据源 foreach (TSource itemMany in source) { //利用foreach()和collectionSelector()委托,循环遍历需要解析的字段 foreach (TCollection itemone in collectionSelector(itemMany)) { //进行判断 if(itemone!=null){ //创建一个返回对象 TResult tResult=default(TResult); //利用resultSelector()委托,将返回值赋给返回对象 tResult = resultSelector(itemMany, itemone); //将返回值对象添加到返回值对象集合中 listTResult.Add(tResult); } } } return listTResult; } } ``` ####微软官方并未对该方法进行为空处理,若用户在使用官方的List<T>.SelectMany()方法时在第一个委托解析数据时使用DefaultIfEmpty()运行时会报错,我们个人实现该方法可实现为空不报错功能,如下: #####.如果解析后值为空,我们可以预先实例化一个对象,将对象空值赋于返回值对象,但是使用`TCollection tCollection = new TCollection();`,其会报变量类型没有new()约束的错误,若我们在拓展方法后加上`whewe TCollection:new()`则代码就多了限制,代码耦合度就高了,所以我们使用反射(利用类型创建对象),即:`类型 类型名=Activator.CreateInstance<类型名>();`,就解决了。 ##为空处理后完整代码: ```csharp //拓展方法创建 public static class SelectManyExtands { public static IEnumerable<TResult> MySelectMany<TSource, TCollection, TResult>(this IEnumerable<TSource> source, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource,TCollection, TResult> resultSelector) { //创建一个返回值对象集合 List<TResult> listTResult = new List<TResult>(); //利用foreach()循环遍历数据源 foreach (TSource itemMany in source) { //利用foreach()和collectionSelector()委托,循环遍历需要解析的字段 foreach (TCollection itemone in collectionSelector(itemMany)) { //创建一个返回对象 TResult tResult=default(TResult); //判断itemtwo是否为空,如果为空则预先利用反射(使用类型创建对象)创建一个对象,代替为空的itemone传入resultSelector()委托中去 if(itemone==null){ //利用反射,使用类型创建对象 TCollection tcollection=Activator.CreateInstance<TCollection>(); //利用resultSelector()委托,反射传创建的对象tcollection代替itemone传入委托,将返回值赋给返回对象 tResult = resultSelector(itemMany,tcollection); }else{ //利用resultSelector()委托,将返回值赋给返回对象 tResult = resultSelector(itemMany, itemone); } //将返回值对象添加到返回值对象集合中 listTResult.Add(tResult); } } return listTResult; } } ```
👈{{preArticle.title}}
👉{{nextArticle.title}}
评价
{{titleitem}}
{{titleitem}}
{{item.content}}
{{titleitem}}
{{titleitem}}
{{item.content}}