【问题标题】:How to trim all strings from a complex object returned with dapper如何从使用 dapper 返回的复杂对象中修剪所有字符串
【发布时间】:2019-02-19 10:56:13
【问题描述】:

我正在使用旧数据库,在这个数据库中,数据被分配了列的最大长度。如果字符串数据比较短,会在末尾自动填充空格。

我要做的是在我执行的每个查询中修剪所有这些结尾的空格。

我认为更好的方法之一是使用反射为 dapper 查询创建扩展方法。

但我似乎无法让它工作。

父实体:

public class Person: BaseEntity
   {
       public Identification Identification { get; set; }
       public Address Address { get; set; }
       public Contact Contact { get; set; }
       public Family Family { get; set; }
       public ICollection<Payment> Payments { get; set; }
   }

子实体示例:

 public class Address: BaseEntity
    {
        public string Street { get; set;  }
        public int Number { get; set; }
        public string BoxNumber { get; set; }
        public int ZipCode { get; set; }
        public string City { get; set; }
        public string Country { get; set; }
    }

现在我像这样进行连接查询:


var result = _db.QueryTrim<dynamic>(sql, new { userid = id })
                .Select(p => new Person()
                {
Identification = IdentificationMapper.MapToIdentificationEntity(p),
                    Address = AddressMapper.MapToAddressEntity(p)}).First();

我正在尝试实现类似的东西,但我无法让它与查询一起使用

public static class DapperExtensions {
    public static IEnumerable<T> Query<T>(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) {
        var dapperResult = SqlMapper.Query<T>(cnn, sql, param, transaction, buffered, commandTimeout, commandType);
        var result = TrimStrings(dapperResult.ToList());
        return result;
    }

    static IEnumerable<T> TrimStrings<T>(IList<T> objects) {
        //todo: create an Attribute that can designate that a property shouldn't be trimmed if we need it
        var publicInstanceStringProperties = typeof (T).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => x.PropertyType == typeof (string) && x.CanRead &&  x.CanWrite);
        foreach (var prop in publicInstanceStringProperties) {
            foreach (var obj in objects) {
                var value = (string) prop.GetValue(obj);
                var trimmedValue = value.SafeTrim();
                prop.SetValue(obj, trimmedValue);
            }
        }
        return objects;
    }

    static string SafeTrim(this string source) {
        if (source == null) {
            return null;
        }
        return source.Trim();
    }
}

最后我想修剪来自数据库的所有字符串。目前我正在对 dapperextension 进行隧道视觉,但如果有更好的方法。请告诉我。

【问题讨论】:

  • 在 SQL 中执行?
  • @DavidG 问题是我事先不知道哪些列需要修剪,哪些不需要
  • 你怎么会事先不知道呢?您确定知道要修剪哪些列吗?
  • 嗯,也许你是对的。我会尝试以这种方式实现它。与此同时,我将尝试使用一个小巧的扩展,所以我不必总是在查询中编写 RTRIM
  • 我第二个@DavidG。这也将减少从数据库传输的数据量。

标签: c# .net reflection dapper


【解决方案1】:

如果您使用的是 Dapper 1.50.2 版,则可以使用更简单的方式。

像下面这样创建一个 TypeHandler:

public class TrimmedStringHandler : SqlMapper.TypeHandler<string>
{
    public override string Parse(object value)
    {
        string result = (value as string)?.Trim();
        return result;
    }

    public override void SetValue(IDbDataParameter parameter, string value)
    {
        parameter.Value = value;
    }
}

在程序初始化时,您必须调用 SqlMapper 类的 AddTypeHandler 方法,如下所示:

SqlMapper.AddTypeHandler(new TrimmedStringHandler());

如果这样做,来自数据库的每个字符串都将被修剪。

【讨论】:

  • 这对我来说非常有效。它似乎也更容易实现。
  • 漂亮的解决方案!完美运行。
猜你喜欢
  • 2022-11-01
  • 1970-01-01
  • 2011-10-09
  • 2017-08-20
  • 2012-07-14
  • 1970-01-01
  • 1970-01-01
  • 2014-03-26
  • 2012-05-30
相关资源
最近更新 更多