排名
6
文章
6
粉丝
16
评论
8
{{item.articleTitle}}
{{item.blogName}} : {{item.content}}
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:
50010702506256
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;
}欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739。有需要软件开发,或者学习软件技术的朋友可以和我联系~(Q:815170684)
评价