.net core 反射特性使用,反射通过特性匹配需要的字段赋值 电脑版发表于:2021/11/7 11:49 有这样一个需求,数据库查询出来是这样的数据 <img src="https://img.tnblog.net/arcimg/aojiancc2/33a1b59aff2c418e8919f80f383d45ce.png" style="width:500px;height:auto;"> 要根据tag来获取数据给字段赋值,这种情况一般是使用行专列处理后在前台显示,但是我们这里需求有点特殊,也不太好使用行专列来处理。如果直接写死代码的话就是这个样子 ``` var tagCountListAll = BaseDal.Db.Queryable<StuElevateAssignment>(). Where(a => classIdlist.Contains(a.ClassId) && a.DAStatus != 1 && a.ASSType == _params.ASSType && a.CreateTime >= _params.dateTime && a.CreateTime < nextDay) .GroupBy(a => new { a.Tag, a.ClassId }).Select(a => new { ClassId = a.ClassId, Tag = a.Tag, Count = SqlFunc.AggregateCount(a.Tag), }).ToList(); foreach (VClassTeam item in vClassTeams) { var tagCountList = tagCountListAll.Where(a => a.ClassId == item.ID).ToList(); ClassStatisticsShowStyleDto classStatisticsDto = new ClassStatisticsShowStyleDto(); classStatisticsDto.ClassId = item.ID; classStatisticsDto.ClassName = item.ClassName; if (tagCountList.First(a => a.Tag == "plank") == null) { classStatisticsDto.PlankCount = "/"; } else { classStatisticsDto.PlankCount = tagCountList.First(a => a.Tag == "plank").Count + ""; } if (tagCountList.First(a => a.Tag == "仰卧起坐") == null) { classStatisticsDto.SitUpsCount = "/"; } else { classStatisticsDto.SitUpsCount = tagCountList.First(a => a.Tag == "仰卧起坐").Count + ""; } if (tagCountList.First(a => a.Tag == "俯卧撑") == null) { classStatisticsDto.PushUpCount = "/"; } else { classStatisticsDto.PushUpCount = tagCountList.First(a => a.Tag == "俯卧撑").Count + ""; } if (tagCountList.First(a => a.Tag == "健身房锻炼") == null) { classStatisticsDto.GymExerciseCount = "/"; } else { classStatisticsDto.GymExerciseCount = tagCountList.First(a => a.Tag == "健身房锻炼").Count + ""; } if (tagCountList.First(a => a.Tag == "其它") == null) { classStatisticsDto.OtherCount = "/"; } else { classStatisticsDto.OtherCount = tagCountList.First(a => a.Tag == "其它").Count + ""; } if (tagCountList.First(a => a.Tag == "球类运动") == null) { classStatisticsDto.BallCount = "/"; } else { classStatisticsDto.BallCount = tagCountList.First(a => a.Tag == "球类运动").Count + ""; } if (tagCountList.First(a => a.Tag == "田径类") == null) { classStatisticsDto.TrackCount = "/"; } else { classStatisticsDto.TrackCount = tagCountList.First(a => a.Tag == "田径类").Count + ""; } if (tagCountList.First(a => a.Tag == "跳绳") == null) { classStatisticsDto.RopeSkippingCount = "/"; } else { classStatisticsDto.RopeSkippingCount = tagCountList.First(a => a.Tag == "跳绳").Count + ""; } classStatisticsDtoList.Add(classStatisticsDto); } ``` 这种代码写起来就太不灵活了,太硬编码了,而且我们这里类型还不止这些,这样写的话代码会写得超级长,很难受,如果这里的类型有做数据字典的情况还会,用这里的tag和数据字典的字段匹配实体的属性名,用来反射给实体的属性赋值就行了,但是这里设计数据库的太坑了,数据字典也没有,所以我们只能想其他方法了,这里就可以考虑用特性来做一个映射,然后在使用反射。 **配置特性,其实就是让中文的tag和字段做一个映射,有了这个映射就可以使用反射来赋值了** ``` public class ClassStatisticsShowStyleDto { public string ClassName { get; set; } public string ClassId { get; set; } [DisplayName("plank")] public string PlankCount { get; set; } [DisplayName("仰卧起坐")] public string SitUpsCount { get; set; } [DisplayName("俯卧撑")] public string PushUpCount { get; set; } [DisplayName("跳绳")] public string RopeSkippingCount { get; set; } [DisplayName("田径类")] public string TrackCount { get; set; } [DisplayName("球类运动")] public string BallCount { get; set; } [DisplayName("健身房锻炼")] public string GymExerciseCount { get; set; } [DisplayName("其它")] public string OtherCount { get; set; } } ``` 有了这个映射就可以使用反射来赋值了: ``` var tagCountListAll = BaseDal.Db.Queryable<StuElevateAssignment>(). Where(a => classIdlist.Contains(a.ClassId) && a.DAStatus != 1 && a.ASSType == _params.ASSType && a.CreateTime >= _params.dateTime && a.CreateTime < nextDay) .GroupBy(a => new { a.Tag, a.ClassId }).Select(a => new { ClassId = a.ClassId, Tag = a.Tag, Count = SqlFunc.AggregateCount(a.Tag), }).ToList(); foreach (VClassTeam item in vClassTeams) { var tagCountList = tagCountListAll.Where(a => a.ClassId == item.ID).ToList(); ClassStatisticsShowStyleDto classStatisticsDto = new ClassStatisticsShowStyleDto(); classStatisticsDto.ClassId = item.ID; classStatisticsDto.ClassName = item.ClassName; // 反射获取所有属性。用反射来代替下面的写死数据查询 PropertyInfo[] properties = classStatisticsDto.GetType().GetProperties(); foreach (PropertyInfo propertyInfo in properties) { var attrs = propertyInfo.GetCustomAttributes(typeof(DisplayNameAttribute), true); if (attrs != null) { if (attrs.Length > 0) { var displayName = ((DisplayNameAttribute)attrs[0]).DisplayName; // 用特性来找到需要的数据在赋值 if (!string.IsNullOrWhiteSpace(displayName)) { if (tagCountList.FirstOrDefault(a => a.Tag == displayName) == null) { //classStatisticsDto.PlankCount = "/"; propertyInfo.SetValue(classStatisticsDto, "/"); } else { //classStatisticsDto.PlankCount = tagCountList.First(a => a.Tag == displayName).Count + ""; propertyInfo.SetValue(classStatisticsDto, tagCountList.First(a => a.Tag == displayName).Count + ""); } } } } } } ```