【问题标题】:Possible to display two query results side by side in LinqPad?可以在 LinqPad 中并排显示两个查询结果吗?
【发布时间】:2018-07-20 21:08:10
【问题描述】:

我想知道是否可以并排显示两个查询结果而不是在 LinqPad 中从上到下显示? 即用两个不同的查询提取相同的记录,以便我可以并排查看以比较数据?

【问题讨论】:

  • 您可以将结果合并为一个IEnumerable,即使用join?它只是一个记录还是一个记录表?

标签: linqpad


【解决方案1】:

使用一些扩展方法,您可以将任何Object 转换为代表字段和属性及其值的Dictionary<string,object>。然后你就可以加入他们了。

TypeMemberInfo 上的一些扩展方法可以更轻松地一起使用属性和字段:

public static class TypeExt {
    public static MemberInfo[] GetPropertiesOrFields(this Type t, BindingFlags bf = BindingFlags.Public | BindingFlags.Instance) =>
        t.GetMembers(bf).Where(mi => mi.MemberType == MemberTypes.Field | mi.MemberType == MemberTypes.Property).ToArray();
}

public static class MemberInfoExt {
    public static object GetValue(this MemberInfo member, object srcObject) {
        switch (member) {
            case FieldInfo mfi:
                return mfi.GetValue(srcObject);
            case PropertyInfo mpi:
                return mpi.GetValue(srcObject);
            default:
                throw new ArgumentException("MemberInfo must be of type FieldInfo or PropertyInfo", nameof(member));
        }
    }
}

使用这些助手,您可以将object 转换为Dictionary<string,object>

public static class ObjectExt {
    public static IDictionary<string, object> ToDictionary(this object item) {
        if (item is IDictionary<string, object> id)
            return id;
        else {
            var dictAnsObj = new Dictionary<string, object>();

            foreach (var prop in item.GetType().GetPropertiesOrFields()) {
                try {
                    dictAnsObj.Add(prop.Name, prop.GetValue(item));
                }
                catch (Exception ex) {
                    dictAnsObj.Add(prop.Name, ex);
                }
            }

            return dictAnsObj;
        }
    }

    public class SideBySideClass {
        public string Key;
        public object Left;
        public object Right;
    }

    public static IEnumerable<SideBySideClass> SideBySide(this object left, object right) {
        return left.ToDictionary()
                   .Join(right.ToDictionary(),
                         kvp => kvp.Key,
                         kvp => kvp.Key,
                         (l, r) => new SideBySideClass() { Key = l.Key, Left = l.Value, Right = r.Value })
                   .OrderBy(sxs => sxs.Key);
    }
}

objects 转换为两个字典后,很容易将它们加入成员名称,然后 LINQPad 将它们并排输出。如果r1r2是你的单条记录,那么:

r1.SideBySide(r2).Dump();

将它们并排输出。

使用一些小的更改,您可以添加另一列来显示哪些值不同。

你也可以join一些id字段的两组记录,并排输出。这是一个扩展方法:

public static IEnumerable<IEnumerable<SideBySideClass>> SidesBySides<T, TKey>(this IEnumerable<T> lefts, IEnumerable<T> rights, Func<T,TKey> keyFn) =>
    lefts.Join(rights, keyFn, keyFn, (l, r) => l.SideBySide(r));

【讨论】:

    【解决方案2】:

    一个轻量级的选择是创建一个 Tuple 数组,然后从那里开始:

    Person a = GetA();
    Person b = GetB();
    
    Tuple<Person, Person> tup = new Tuple<Person, Person>(a, b);
    Tuple<Person, Person>[] tupArray = new[] { tup };
    tupArray.Dump(1);
    

    【讨论】:

      猜你喜欢
      • 2012-12-26
      • 2015-02-25
      • 1970-01-01
      • 2022-06-16
      • 1970-01-01
      • 2016-01-12
      • 1970-01-01
      • 1970-01-01
      • 2011-02-17
      相关资源
      最近更新 更多