本文介绍了创建动态group by子句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下小组:





Hi peeps I have the following group by :


var groupedData = outputTable.AsEnumerable()
    .GroupBy(x => new { name = x.Field<string>("name"), source = x.Field<string>     ("source"), destination = x.Field<string>("destination") }).ToList();





这是有效的,但源和目标可以是我从数据库中提取的任何内容,因为我需要使这些分组动态化。所以我想构建一种这样的组字符串:





this works but source and destination could be anything that I pull from the database as I need to make these groupings dynamic. So I want to build a kind of group string like this :

string dyno = "name = x.Field(\"name\"), sourceAddress = x.Field(\"sourceAddress\"), destinationAddress = x.Field(\"destinationAddress\")";





然后说:



and then say:

var groupedData = outputTable.AsEnumerable()
    .GroupBy(x => new { dyno }).ToList();





这可能吗?



我尝试了什么:





is this possible?

What I have tried:

string bob = "name = x.Field<string>(\"name\"), sourceAddress = x.Field<string>(\"sourceAddress\"), destinationAddress = x.Field<string>(\"destinationAddress\")";

var groupedData = outputTable.AsEnumerable().GroupBy(x => new { x =>  bob }).ToList();

推荐答案


public sealed class DynamicDataRowGroup : DynamicObject, ICustomTypeDescriptor, IEquatable<DynamicDataRowGroup>
{
    private readonly DataRow _row;
    private readonly ISet<string> _columns;
    private readonly PropertyDescriptorCollection _properties;

    public DynamicDataRowGroup(DataRow row, IEnumerable<string> columns)
    {
        if (row == null) throw new ArgumentNullException("row");
        if (columns == null) throw new ArgumentNullException("columns");

        _row = row;
        _columns = new HashSet<string>(columns, StringComparer.OrdinalIgnoreCase);

        var properties = _columns.Select(name => DynamicDataRowGroupProperty.Create(row, name));
        _properties = new PropertyDescriptorCollection(properties.ToArray<PropertyDescriptor>(), true);
    }

    public DynamicDataRowGroup(DataRow row, params string[] columns) : this(row, columns.AsEnumerable())
    {
    }

    public override int GetHashCode()
    {
        int result = 0;
        foreach (string column in _columns)
        {
            object value = _row[column];
            int code = (value == null) ? 0 : value.GetHashCode();
            result = unchecked((result * 397) + code);
        }

        return result;
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as DynamicDataRowGroup);
    }

    public bool Equals(DynamicDataRowGroup other)
    {
        if (ReferenceEquals(other, null)) return false;
        if (ReferenceEquals(other, this)) return true;
        if (!_columns.SetEquals(other._columns)) return false;
        return _columns.All(c => Equals(_row[c], other._row[c]));
    }

    public override IEnumerable<string> GetDynamicMemberNames()
    {
        return _columns;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        if (_columns.Contains(binder.Name))
        {
            result = _row[binder.Name];
            return true;
        }

        return base.TryGetMember(binder, out result);
    }

    public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
    {
        if (indexes != null && indexes.Length == 1)
        {
            string name = indexes[0] as string;
            if (name != null && _columns.Contains(name))
            {
                result = _row[name];
                return true;
            }
        }

        return base.TryGetIndex(binder, indexes, out result);
    }

    PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
    {
        return _properties;
    }

    PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
    {
        return _properties;
    }

    object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd)
    {
        return this;
    }

    PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty()
    {
        return null;
    }

    AttributeCollection ICustomTypeDescriptor.GetAttributes()
    {
        return AttributeCollection.Empty;
    }

    EventDescriptorCollection ICustomTypeDescriptor.GetEvents()
    {
        return EventDescriptorCollection.Empty;
    }

    EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes)
    {
        return EventDescriptorCollection.Empty;
    }

    EventDescriptor ICustomTypeDescriptor.GetDefaultEvent()
    {
        return null;
    }

    string ICustomTypeDescriptor.GetClassName()
    {
        return null;
    }

    string ICustomTypeDescriptor.GetComponentName()
    {
        return null;
    }

    TypeConverter ICustomTypeDescriptor.GetConverter()
    {
        return null;
    }

    object ICustomTypeDescriptor.GetEditor(Type editorBaseType)
    {
        return null;
    }

    private sealed class DynamicDataRowGroupProperty : PropertyDescriptor
    {
        private static readonly Attribute[] EmptyAttributes = new Attribute[0];
        private readonly Type _propertyType;

        private DynamicDataRowGroupProperty(string name, Type propertyType) : base(name, EmptyAttributes)
        {
            _propertyType = propertyType;
        }

        public override Type ComponentType
        {
            get { return typeof(DynamicDataRowGroup); }
        }

        public override Type PropertyType
        {
            get { return _propertyType; }
        }

        public override bool IsReadOnly
        {
            get { return true; }
        }

        public override object GetValue(object component)
        {
            var group = component as DynamicDataRowGroup;
            return (group == null) ? null : group._row[Name];
        }

        public override bool ShouldSerializeValue(object component)
        {
            return false;
        }

        public override bool CanResetValue(object component)
        {
            return false;
        }

        public override void ResetValue(object component)
        {
            throw new NotSupportedException();
        }

        public override void SetValue(object component, object value)
        {
            throw new NotSupportedException();
        }

        public static DynamicDataRowGroupProperty Create(DataRow row, string name)
        {
            DataColumn column = row.Table.Columns[name];
            if (column == null) throw new ArgumentException(string.Format("Column '{0}' was not found.", name));
            return new DynamicDataRowGroupProperty(name, column.DataType);
        }
    }
}



有了这个类,你现在可以像这样对行进行分组:


With that class in place, you can now group your rows like this:

var groupedData = outputTable.AsEnumerable()
    .GroupBy(row => new DynamicDataRowGroup(row, "name", "sourceAddress", "destinationAddress"))
    .ToList();



你可以将密钥转换为 dynamic 并直接访问属性:


You can either cast the keys to dynamic and access the properties directly:

dynamic key = groupedData[0].Key;
string name = key.name;



或者您可以使用任何依赖的绑定机制 TypeDescriptor (例如ASP.NET中的 Eval )来检索属性:


Or you can use any binding mechanism that relies on the TypeDescriptor (such as Eval in ASP.NET) to retrieve the properties:

<asp:literal runat="server"

    Text='<%# Eval("Key.name") %>'

/>


这篇关于创建动态group by子句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 03:49