属性映射服务实现

public class PropertyMappingValue
{
public IEnumerable<string> DestinationProperties { get; private set; }
public PropertyMappingValue(IEnumerable<string> destinationProperties)
{
DestinationProperties = destinationProperties;
}
}
public class PropertyMapping<TSource, TDestination> : IPropertyMapping
{
public Dictionary<string, PropertyMappingValue> _mappingDictionary { get; set; }
public PropertyMapping(Dictionary<string, PropertyMappingValue> mappingDictionary)
{
_mappingDictionary = mappingDictionary;
}
}
public class PropertyMappingService : IPropertyMappingService
{
//PropertyMapping
private Dictionary<string, PropertyMappingValue> _touristRoutePropertyMapping =
new Dictionary<string, PropertyMappingValue>(StringComparer.OrdinalIgnoreCase)
{
{"Id", new PropertyMappingValue(new List<string>(){"Id"}) },
{"Title", new PropertyMappingValue(new List<string>(){"Title"}) },
{"Rating", new PropertyMappingValue(new List<string>(){"Rating"}) },
{"OriginalPrice", new PropertyMappingValue(new List<string>(){"OriginalPrice"})},
}; //PropertyMappings
private IList<IPropertyMapping> _propertyMappings
= new List<IPropertyMapping>(); public PropertyMappingService()
{
_propertyMappings.Add(
new PropertyMapping<TouristRouteDto, TouristRoute> (_touristRoutePropertyMapping)
);
} //GetPropertyMapping
public Dictionary<string, PropertyMappingValue>
GetPropertyMapping<TSource, TDestination>()
{
var matchingMapping =
_propertyMappings.OfType<PropertyMapping<TSource, TDestination>>(); if (matchingMapping.Count() == 1)
{
return matchingMapping.First()._mappingDictionary;
}
throw new Exception($"Cannot find exact property mapping instance for <{typeof(TSource)}, {typeof(TDestination)}>");
} //IsMappingExists
public bool IsMappingExists<TSource, TDestination>(string fields)
{
var propertyMapping = GetPropertyMapping<TSource, TDestination>(); if (string.IsNullOrWhiteSpace(fields))
{
return true;
} var fieldsAfterSplit = fields.Split(","); foreach (var field in fieldsAfterSplit)
{
var trimmedField = field.Trim();
var indexOfFirstSpace = trimmedField.IndexOf(" ");
var propertyName = indexOfFirstSpace == -1 ?
trimmedField : trimmedField.Remove(indexOfFirstSpace); if (!propertyMapping.ContainsKey(propertyName))
{
return false;
}
}
return true;
} //IsPropertiesExists
public bool IsPropertiesExists<T>(string fields)
{
if (string.IsNullOrWhiteSpace(fields))
{
return true;
}
var fieldsAfterSplit = fields.Split(',');
foreach (var field in fieldsAfterSplit)
{
var propertyName = field.Trim();
var propertyInfo = typeof(T)
.GetProperty(
propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance
); if (propertyInfo == null)
{
return false;
}
}
return true;
}
}

注入服务

动态排序

在Helper中扩展IQueryable封装了ApplySort方法实现动态排序

public static class IQueryableExtensions
{
public static IQueryable<T> ApplySort<T>(
this IQueryable<T> source,
string orderBy,
Dictionary<string, PropertyMappingValue> mappingDictionary
)
{
if (source == null)
{
throw new ArgumentNullException("source");
} if (mappingDictionary == null)
{
throw new ArgumentNullException("mappingDictionary");
} if (string.IsNullOrWhiteSpace(orderBy))
{
return source;
} var orderByString = string.Empty; var orderByAfterSplit = orderBy.Split(','); foreach (var order in orderByAfterSplit)
{
var trimmedOrder = order.Trim(); var orderDescending = trimmedOrder.EndsWith(" desc"); var indexOfFirstSpace = trimmedOrder.IndexOf(" ");
var propertyName = indexOfFirstSpace == -1
? trimmedOrder
: trimmedOrder.Remove(indexOfFirstSpace); if (!mappingDictionary.ContainsKey(propertyName))
{
throw new ArgumentException($"Key mapping for {propertyName} is missing");
} var propertyMappingValue = mappingDictionary[propertyName];
if (propertyMappingValue == null)
{
throw new ArgumentNullException("propertyMappingValue");
} foreach (var destinationProperty in
propertyMappingValue.DestinationProperties)
{
orderByString = orderByString +
(string.IsNullOrWhiteSpace(orderByString) ? string.Empty : ", ")
+ destinationProperty
+ (orderDescending ? " descending" : " ascending");
}
}
return source.OrderBy(orderByString);
}
}

在repository中使用

数据塑形

安装Nuget包

在Helper中封装了IEnumerableExtensions、ObjectExtensions,实现对数据的动态塑形。

public static class IEnumerableExtensions
{
public static IEnumerable<ExpandoObject> ShapeData<TSource>(
this IEnumerable<TSource> source,
string fields
)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
} var expandoObjectList = new List<ExpandoObject>(); //避免在列表中遍历数据,创建一个属性信息列表
var propertyInfoList = new List<PropertyInfo>(); if (string.IsNullOrWhiteSpace(fields))
{
// 希望返回动态类型对象ExpandoObject所有的属性
var propertyInfos = typeof(TSource)
.GetProperties(BindingFlags.IgnoreCase
| BindingFlags.Public | BindingFlags.Instance); propertyInfoList.AddRange(propertyInfos);
}
else
{
//逗号来分隔字段字符串
var fieldsAfterSplit = fields.Split(','); foreach (var filed in fieldsAfterSplit)
{
// 去掉首尾多余的空格,获得属性名称
var propertyName = filed.Trim(); var propertyInfo = typeof(TSource)
.GetProperty(propertyName, BindingFlags.IgnoreCase
| BindingFlags.Public | BindingFlags.Instance); if (propertyInfo == null)
{
throw new Exception($"属性 {propertyName} 找不到" +
$" {typeof(TSource)}");
} propertyInfoList.Add(propertyInfo);
}
} foreach (TSource sourceObject in source)
{
// 创建动态类型对象, 创建数据塑性对象
var dataShapedObject = new ExpandoObject
foreach (var propertyInfo in propertyInfoList)
{
//获得对应属性的真实数据
var propertyValue = propertyInfo.GetValue(sourceObjec
((IDictionary<string, object>)dataShapedObject)
.Add(propertyInfo.Name, propertyValue); expandoObjectList.Add(dataShapedObject);
} return expandoObjectList;
}
}
public static class ObjectExtensions
{
public static ExpandoObject ShapeData<TSource>(
this TSource source,
string fields
)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
} var dataShapedObject = new ExpandoObject(); if (string.IsNullOrWhiteSpace(fields))
{
var propertyInfos = typeof(TSource)
.GetProperties(BindingFlags.IgnoreCase |
BindingFlags.Public | BindingFlags.Instance); foreach (var propertyInfo in propertyInfos)
{
var propertyValue = propertyInfo.GetValue(source); ((IDictionary<string, object>)dataShapedObject)
.Add(propertyInfo.Name, propertyValue);
} return dataShapedObject;
} var fieldsAfterSplit = fields.Split(','); foreach (var field in fieldsAfterSplit)
{
var propertyName = field.Trim(); var propertyInfo = typeof(TSource)
.GetProperty(propertyName,
BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); if (propertyInfo == null)
{
throw new Exception($"Property {propertyName} wasn't found " +
$"on {typeof(TSource)}");
} var propertyValue = propertyInfo.GetValue(source); ((IDictionary<string, object>)dataShapedObject)
.Add(propertyInfo.Name, propertyValue);
} return dataShapedObject;
}
}

在控制器的Action中使用

在Asp .net core 中通过属性映射实现动态排序和数据塑形的更多相关文章

  1. ASP.NET Core 中的对象映射之 AutoMapper

    目录 AutoMapper 简介 AutoMapper 使用 初始化 Profile设置 扁平化映射 集合映射 投影 条件映射 值转换 设置转换前后行为 配置验证及设置 反向映射 自定义转换器 自定义 ...

  2. 为什么我的会话状态在ASP.NET Core中不工作了?

    原文:Why isn't my session state working in ASP.NET Core? Session state, GDPR, and non-essential cookie ...

  3. 如何在 ASP.NET Core 中构建轻量级服务

    在 ASP.NET Core 中处理 Web 应用程序时,我们可能经常希望构建轻量级服务,也就是没有模板或控制器类的服务. 轻量级服务可以降低资源消耗,而且能够提高性能.我们可以在 Startup 或 ...

  4. 项目开发中的一些注意事项以及技巧总结 基于Repository模式设计项目架构—你可以参考的项目架构设计 Asp.Net Core中使用RSA加密 EF Core中的多对多映射如何实现? asp.net core下的如何给网站做安全设置 获取服务端https证书 Js异常捕获

    项目开发中的一些注意事项以及技巧总结   1.jquery采用ajax向后端请求时,MVC框架并不能返回View的数据,也就是一般我们使用View().PartialView()等,只能返回json以 ...

  5. ASP.NET Core Web 应用程序系列(五)- 在ASP.NET Core中使用AutoMapper进行实体映射

    本章主要简单介绍下在ASP.NET Core中如何使用AutoMapper进行实体映射.在正式进入主题之前我们来看下几个概念: 1.数据库持久化对象PO(Persistent Object):顾名思义 ...

  6. ASP.NET CORE 中使用AutoMapper进行对象映射

    ASP.NET CORE 中使用AutoMapper进行对象映射 1.什么是AutoMapper? AutoMapper是基于对象到对象约定的映射工具,常用于(但并不仅限制于)把复杂的对象模型转为DT ...

  7. ASP.NET Core中使用IOC三部曲(二.采用Autofac来替换IOC容器,并实现属性注入)

    前言 本文主要是详解一下在ASP.NET Core中,自带的IOC容器相关的使用方式和注入类型的生命周期. 这里就不详细的赘述IOC是什么 以及DI是什么了.. emm..不懂的可以自行百度. 目录 ...

  8. ASP.NET Core中使用自定义MVC过滤器属性的依赖注入

    除了将自己的中间件添加到ASP.NET MVC Core应用程序管道之外,您还可以使用自定义MVC过滤器属性来控制响应,并有选择地将它们应用于整个控制器或控制器操作. ASP.NET Core中常用的 ...

  9. ASP.NET Core中如果Response.HasStarted已经为true,就不能更改Response.Cookies和Response.Headers等属性的值了

    最近我在ASP.NET Core中做了一个中间件CustomizedMiddleware,要说该中间件的功能也很简单,其实就是往HttpResponse中添加一个Cookie而已,但是我将添加Cook ...

随机推荐

  1. mysql学习--MySQL存储引擎对比总结

    一.存储引擎是什么 存储引擎是数据库的核心,对于mysql来说,存储引擎是以插件的形式运行的.MySQL默认配置了许多不同的存储引擎,可以预先设置或者在MySQL服务器中启用.你可以选择适用于服务器. ...

  2. 【笔记】Python编程 从入门到实践 第二版(基础部分)

    1 字符串相关函数 .title() # 将字符串每个单词的首字母大写 .upper() #不改变字符串变量的值 .lower() #不改变字符串变量的值 f"{var} ,字符串" ...

  3. c语言函数的嵌套使用和矩阵运算

    这段时间,听刚刚学习c的同学说函数嵌套运用不太熟练,想做一个简单的程序进行练习,我也就当练练手了,哈哈.虽然说是比较简单,但是其中的思维也是值得思考的. 一.函数的嵌套使用 简单说明题目:对于等式 y ...

  4. JMeter之Throughput Controller吞吐量控制器

    吞吐量控制器,它是用来控制该控制器下面元件的执行次数,与控制吞吐量的功能无关.(注:用Constant Throughput Timer可以控制吞吐量tps) 作用:控制其子节点的执行次数与负载比例分 ...

  5. 基于SSM小区物业管理系统

    随着计算机的不断发展和广泛应用,人们的工作效率得到不断的提高.互联网的发展,更是缩短了人们之间的距离.如何充分利用互联网,这是大家共同关心的问题.本文主要介绍了关于小区管理系统的实现方法,设计规划了小 ...

  6. cisco 交换机 IOS命令

    1 显示交换机的MAC地址表 user mode : show mac-address-table

  7. Java-数组有关

    1.复制数组 复制数组主要有三类方法: 1.使用循环语句逐个赋值数组元素 2.使用System类中的静态方法arraycopy 3.使用clone方法复制数组 对于2,详述如下: arraycopy( ...

  8. Linux CentOS 7 在Apache服务器上安装SSL证书

    在开发微信小程序的时候,wx.request请求的地址必须是https的,所以只能重新配置服务器. 域名和服务器都是在阿里云上买的,系统是CentOS7,安装了Apache服务器.网上也找了一下,很多 ...

  9. Dijkstra和堆优化

    Dijkstra算法 由于我之前一直记的迪杰斯特拉的翻译导致我把dijkstra写成了dijstra--所以下文#define dijstra dijkstra 我以后叫她迪杰克斯歘! Dijskra ...

  10. 【动态规划DP】[USACO16OPEN]248

    题目描述 Bessie likes downloading games to play on her cell phone, even though she doesfind the small to ...