问题描述
我有以下小组:
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子句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!