Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从列表值c动态创建匿名对象#_C#_Linq_Group By_Anonymous Types_Idictionary - Fatal编程技术网

C# 从列表值c动态创建匿名对象#

C# 从列表值c动态创建匿名对象#,c#,linq,group-by,anonymous-types,idictionary,C#,Linq,Group By,Anonymous Types,Idictionary,我有一个字符串列表(或者可以是数组),我想从中动态创建匿名对象。我该怎么做 var dataSet = new DataSet(); dataSet.ReadXml(@""); var dataTable = dataSet.Tables[0]; var dataRow = dataTable.Rows[0]; var keys = new List<string> {"Column1","Column2"}; var result = new {keys[0] = dat

我有一个字符串列表(或者可以是数组),我想从中动态创建匿名对象。我该怎么做

var dataSet = new DataSet();
dataSet.ReadXml(@"");
var dataTable = dataSet.Tables[0];
var dataRow = dataTable.Rows[0];    

var keys = new List<string> {"Column1","Column2"};
var result = new {keys[0] = dataRow[keys[0]], keys[1] = dataRow[keys[1]]}

如果我从Key()方法硬编码匿名类型,GroupBy子句就可以工作。基本上,我只需要根据键列表中的值动态设置GroupBy子句。

将问题分解,您想要的是能够根据运行时属性对项目列表进行分组,该属性可以由该项目的一个或多个属性组成。本质上,这意味着您需要一个选择器函数(这是您的
方法),用于将项转换为键

为了让GroupBy工作,它需要能够比较任意两个密钥实例,看看它们是否相等。这意味着密钥需要实现一个有意义的
Equals()
方法,或者您需要一个
IEqualityComparer
实现来为您完成这项工作。在这种情况下,我不必费心创建一个新键,只需编写一个等式比较器,它可以直接比较两个数据行:

var duplicates = dataTable
        .AsEnumerable()
        .GroupBy(r => r, new MyDataRowComparer(keys))
        .Where(c => c.Count() > 1)
        .ToList();


internal class MyDataRowComparer : IEqualityComparer<DataRow>
{
    private readonly string[] _keys;

    public MyDataRowComparer(string[] keys)
    {
        _keys = keys; // keep the keys to compare by.
    }

    public bool Equals(DataRow x, DataRow y)
    {
        // a simple implementation that checks if all the required fields 
        // match. This might need more work.
        bool areEqual = true;
        foreach (var key in _keys)
        {
            areEqual &= (x[key] == y[key]);
        }
        return areEqual;
    }

    public int GetHashCode(DataRow obj)
    {
        // Add implementation here to create an aggregate hashcode.
    }
}    
var duplicates=dataTable
.可计算的()
.GroupBy(r=>r,新的MyDataRowComparer(键))
.Where(c=>c.Count()>1)
.ToList();
内部类MyDataRowComparer:IEqualityComparer
{
私有只读字符串[]\u密钥;
公共MyDataRowComparer(字符串[]键)
{
_keys=keys;//保留要比较的键。
}
公共布尔等于(数据行x、数据行y)
{
//一个简单的实现,它检查所有必需的字段
//匹配。这可能需要更多的工作。
布尔等于真;
foreach(变量键输入_键)
{
areEqual&=(x[key]==y[key]);
}
回报是平等的;
}
public int GetHashCode(DataRow obj)
{
//在此处添加实现以创建聚合哈希代码。
}
}    

我认为您混淆了匿名类型(即席定义但属于强类型对象)和动态类型(可以有任意数量的运行时定义的属性),如果我理解正确的话,这就是您在这里试图做的。我有一种感觉,你需要的是两者都不是。你能详细介绍一下GroupBy的内容,展示一下使用这个匿名对象的代码吗?正如@AvnerShahar Kashtan所说,你很可能混淆了dynamic和anonymous。如果您对从字典创建动态对象感到满意,这可能会有所帮助-@AvnerShahar Kashtan-我在上面的LINQ查询中添加了它。Simon-我以前从您的链接中尝试过该代码,但无法使其正常工作。更具体地说,动态对象似乎没有那个属性。好了,现在更清楚了。您有一个datatable,希望通过一个复合属性对其进行分组,该属性由编译时未知的几列组成。对吧?谢谢你,阿夫纳。我添加了GetHashCode()实现并调整了Equals()。我必须使用object.Equals()函数来比较值,因为==每次都返回false。另一个选项是将ToString()添加到每个值中。
var duplicates = dataTable.AsEnumerable().GroupBy(r => Key(r, keys)).Where(c => c.Count() > 1).ToList();
var duplicates = dataTable
        .AsEnumerable()
        .GroupBy(r => r, new MyDataRowComparer(keys))
        .Where(c => c.Count() > 1)
        .ToList();


internal class MyDataRowComparer : IEqualityComparer<DataRow>
{
    private readonly string[] _keys;

    public MyDataRowComparer(string[] keys)
    {
        _keys = keys; // keep the keys to compare by.
    }

    public bool Equals(DataRow x, DataRow y)
    {
        // a simple implementation that checks if all the required fields 
        // match. This might need more work.
        bool areEqual = true;
        foreach (var key in _keys)
        {
            areEqual &= (x[key] == y[key]);
        }
        return areEqual;
    }

    public int GetHashCode(DataRow obj)
    {
        // Add implementation here to create an aggregate hashcode.
    }
}