Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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#_Linq_Datatable_Functional Programming - Fatal编程技术网

C# 使用动态列数连接数据表的函数方法

C# 使用动态列数连接数据表的函数方法,c#,linq,datatable,functional-programming,C#,Linq,Datatable,Functional Programming,我有一个项目,它允许用户通过左键连接到列表(将通过助手方法转换为数据表)向数据表添加列。目前,我有一个正在运行的实现: public static DataTable ListToDataTable<T>(this IList<T> data) { DataTable dt = new DataTable(); PropertyDescriptorCollection props = TypeDescript

我有一个项目,它允许用户通过左键连接到
列表
(将通过助手方法转换为
数据表
)向
数据表
添加列。目前,我有一个正在运行的实现:

public static DataTable ListToDataTable<T>(this IList<T> data)
        {
            DataTable dt = new DataTable();
            PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T));
            for (int i = 0; i < props.Count; i++)
            {
                PropertyDescriptor prop = props[i];
                dt.Columns.Add(prop.Name, prop.PropertyType);
            }
            object[] values = new object[props.Count];
            foreach (T t in data)
            {
                for (int i = 0; i < values.Length; i++)
                {
                    values[i] = props[i].GetValue(t);
                }
                dt.Rows.Add(values);
            }
            return dt;
        }
        //for purposes of this demo, the first column in leftTable is always the 
        //column that's joined on
        public static DataTable JoinWithList<T>(this DataTable leftTable, IList<T> data,string propertyToAdd)
        {
            var rightTable = new DataTable();
            rightTable = data.ListToDataTable();
            var joiningColumn = leftTable.Columns[0].ColumnName;
            var columnIndex = 0;
            //find the index of type T whose property is the same as leftTable's

            PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T));
            for (int i = 0; i < props.Count; i++)
            {
                PropertyDescriptor prop = props[i];
                if (prop.Name ==joiningColumn)
                {
                    columnIndex = i;
                }
            }
            var results = (from u in leftTable.AsEnumerable()
                          join s in rightTable.AsEnumerable()
                          on u[0] equals s[columnIndex] into ps
                          from p in ps.DefaultIfEmpty()
                          select new
                          {
                              MembershipId = u[0],
                              UserName = u[1],
                              //some sort of function to iterate over and add columns here
                              Salary = p == null ? 0.01 : p[propertyToAdd] = p[propertyToAdd]
                          }).ToList().ListToDataTable();

            return results;
        }
公共静态数据表ListToDataTable(此IList数据)
{
DataTable dt=新的DataTable();
PropertyDescriptorCollection props=TypeDescriptor.GetProperties(typeof(T));
for(int i=0;i
我希望能够传入一个
列表
作为最后一个参数,并且在
选择新
块中,新匿名类型的列数是可变的。

从功能上考虑。 尝试隔离基本情况,并给出可直接转换为所选函数语言的递归定义

让我们看看在伪ML/F#中,
join
的定义是什么:

您需要正确地构建
match
函数,以比较正确的列,以及传递给
map
的函数以构建新行(在我的示例中只是一个元组)

在C#(不太优雅,有一些低效,但希望在填写
Match
Create
后完成)中,通用版本可能如下所示:

    public bool Match<A, B>(A a, B b)
    {
        // Match code
        return true;
    }

    public C Create<A, B, C>(A a, B b)
    {
        // Create new record
        return default(C);
    }

    public IList<C> Join<A, B, C>(IList<A> a, IList<B> b)
    {
        if(!a.Any() || !b.Any()) return new List<C>();
        var aHead = a[0];
        var bMatches = b.Where(bEl => Match(aHead, bEl));
        var newCs = bMatches.Select(bEl => Create<A, B, C>(aHead, bEl)).ToList();
        newCs.AddRange(Join<A, B, C>(a.Skip(1).ToList(), b));  // Recursive call
        return newCs;
    }
公共布尔匹配(A、B)
{
//匹配码
返回true;
}
公共C创建(A、B)
{
//创造新记录
返回默认值(C);
}
公共IList连接(IList a、IList b)
{
如果(!a.Any()| |!b.Any())返回新列表();
提前风险值=a[0];
var bMatches=b.其中(bEl=>Match(前面,bEl));
var newCs=bMatches.Select(bEl=>Create(aHead,bEl)).ToList();
newCs.AddRange(Join(a.Skip(1.ToList(),b));//递归调用
返回newCs;
}

我对ML和F完全不熟悉。就目前而言,您能否为该ML提供一些C#伪代码?这在我看来相当深奥。
    public bool Match<A, B>(A a, B b)
    {
        // Match code
        return true;
    }

    public C Create<A, B, C>(A a, B b)
    {
        // Create new record
        return default(C);
    }

    public IList<C> Join<A, B, C>(IList<A> a, IList<B> b)
    {
        if(!a.Any() || !b.Any()) return new List<C>();
        var aHead = a[0];
        var bMatches = b.Where(bEl => Match(aHead, bEl));
        var newCs = bMatches.Select(bEl => Create<A, B, C>(aHead, bEl)).ToList();
        newCs.AddRange(Join<A, B, C>(a.Skip(1).ToList(), b));  // Recursive call
        return newCs;
    }