排名
6
文章
6
粉丝
16
评论
8
{{item.articleTitle}}
{{item.blogName}} : {{item.content}}
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2024TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术
分类:
EF
自己写一下里边的原理对了解它的用法有很大的帮助,select都作用类似就是把1对多的格式处理成1对1的格式,
比如这里的把UserScoreViewModel格式处理成UserScoreViewModel2
我们要想写通用的扩展方法出来可以先写一个专门的处理UserScoreViewModel格式成UserScoreViewModel2的方法,这样做也便于我们分析和理解问题,特别是如果我们要进行授课,这种方式更能够让人理解,一步一步的深入。
其实很简单就是两个遍历就好
/// <summary> /// 把List<UserScoreViewModel>转换成List<UserScoreViewModel2>格式 /// </summary> public List<UserScoreViewModel2> Parse(List<UserScoreViewModel> source) { List<UserScoreViewModel2> result = new List<UserScoreViewModel2>(); foreach (UserScoreViewModel item in source) { foreach (Score scoreItem in item.scoreList) { UserScoreViewModel2 uscore = new UserScoreViewModel2(); uscore.UserName = item.UserName; uscore.score = scoreItem; result.Add(uscore); } } return result; }
如果要处理一下为空的情况,我们加一个为空验证即可
//解析成1对1的集合 List<UserScoreViewModel2> userScoreViewModel2List = new List<UserScoreViewModel2>(); foreach (UserScoreViewModel item in userScoreList) { foreach (Score score in item.scores.DefaultIfEmpty()) { UserScoreViewModel2 userScoreViewModel2 = new UserScoreViewModel2(); userScoreViewModel2.Id = item.Id; userScoreViewModel2.UserName = item.UserName; userScoreViewModel2.Number = item.Number; if (score != null) { userScoreViewModel2.Sub = score.Sub; userScoreViewModel2.score = score.Score1; } userScoreViewModel2List.Add(userScoreViewModel2); } }
然后我们在去写通用的:
public static class IEnumberExtands { /// <summary> /// 自己实现MySelectMany /// </summary> /// <typeparam name="TSource">对应外面的集合源类型</typeparam> /// <typeparam name="TCollection">集合里边子集合类型</typeparam> /// <typeparam name="TResult">返回值类型</typeparam> /// <returns></returns> public static IEnumerable<TResult> MySelectMany<TSource, TCollection, TResult>(this IEnumerable<TSource> source, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector) { List<TResult> resultList = new List<TResult>(); foreach (TSource tsource in source) { //通过外面传递的lamdba拿到集合 IEnumerable<TCollection> sublist = collectionSelector(tsource); foreach (TCollection item in sublist) { //通过外面传递的lamdba拿到返回对象 TResult result = resultSelector(tsource, item); resultList.Add(result); } } return resultList; } }
上面的方法没有处理为空的情况,如果外面写了DefaultIfEmpty()就容易报错,我们可以选择在外面去处理:
List<UserScoreViewModel2> userScoreList = oaEntities.UserInfo.GroupJoin(oaEntities.Score, a => a.Id, b => b.UserId, (user, score) => new UserScoreViewModel { Id = user.Id, UserName = user.UserName, Number = user.Number, scores = score }).ToList().SelectMany(a => a.scores.DefaultIfEmpty(), (a, b) => { UserScoreViewModel2 ss = new UserScoreViewModel2 { Id = a.Id, UserName = a.UserName, Number = a.Number }; //为空处理 if (b != null) { ss.Sub = b.Sub; ss.score = b.Score1; } return ss; }).ToList();
当然上面哪种方式有点麻烦,我们可以在扩展方法中去处理。我们可以使用反射创建一个默认对象处理一下这种情况,不然我们就只有在外面去处理了
public static IEnumerable<TResult> MySelectMany<TSource, TCollection, TResult>(this IEnumerable<TSource> source, Func<TSource, IEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector) { List<TResult> userScoreViewModel2List = new List<TResult>(); foreach (TSource item in source) { foreach (TCollection score in collectionSelector(item)) { if (score == null) { //使用反射创建对象,避免为空报错,为空的时候我们就给一个默认值 TCollection collobj = Activator.CreateInstance<TCollection>(); TResult tresult = resultSelector(item, collobj); userScoreViewModel2List.Add(tresult); } else { TResult tresult = resultSelector(item, score); userScoreViewModel2List.Add(tresult); } } } return userScoreViewModel2List; }
欢迎加群讨论技术,群:677373950(满了,可以加,但通过不了),2群:656732739
评价