Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.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

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# 通过LINQ从DataTable到DataTable的多个on子句_C#_Linq_Join_Datatable_Alias - Fatal编程技术网

C# 通过LINQ从DataTable到DataTable的多个on子句

C# 通过LINQ从DataTable到DataTable的多个on子句,c#,linq,join,datatable,alias,C#,Linq,Join,Datatable,Alias,我有一个关于林克的问题 我想内部连接两个数据表,代码如下: DataTable dt1 = new DataTable(); DataTable dt2 = new DataTable(); dt1.Columns.Add("TEST1"); dt1.Columns.Add("TEST2"); dt1.Columns.Add("TEST3"); dt1.Columns.Add("TEST4"); dt2.Columns.Add("TES

我有一个关于林克的问题 我想内部连接两个数据表,代码如下:

    DataTable dt1 = new DataTable();
    DataTable dt2 = new DataTable();

    dt1.Columns.Add("TEST1");
    dt1.Columns.Add("TEST2");
    dt1.Columns.Add("TEST3");
    dt1.Columns.Add("TEST4");

    dt2.Columns.Add("TEST2");
    dt2.Columns.Add("TEST5");
    dt2.Columns.Add("TEST6");
    dt2.Columns.Add("TEST7");

    for (int i = 0; i < 10; i++)
    {
        DataRow row = dt1.NewRow();
        row["TEST1"] = "aaa";
        row["TEST2"] = string.Format("bbb-{0}{1}{2}", i, (i % 2 == 0 ? "-" : ""), (i % 2 == 0 ? "ddd" : ""));
        row["TEST3"] = i.ToString();
        row["TEST4"] = "ddd";
        dt1.Rows.Add(row);
    }

    for (int i = 0; i < 8; i++)
    {
        DataRow row = dt2.NewRow();
        row["TEST2"] = "bbb";
        row["TEST5"] = i.ToString();
        row["TEST6"] = i % 2 == 0 ? "ddd" : "";
        row["TEST7"] = "sss";
        dt2.Rows.Add(row);
    }
dt2的描述如下:

  TEST1 TEST5     TEST6  TEST7  
  ----------------------------  
  bbb     0         ddd    sss    
  bbb     1                sss    
  bbb     2         ddd    sss    
  bbb     3                sss    
  bbb     4         ddd    sss    
  bbb     5                sss    
  bbb     6         ddd    sss    
  bbb     7                sss    
第一个问题是,我想加入dt1和dt2

 TEST2     TEST3   TEST7
---------------------------
bbb-0-ddd   0       sss
bbb-1       1       sss
bbb-2-ddd   2       sss
bbb-3       3       sss
bbb-4-ddd   4       sss
bbb-5       5       sss
bbb-6-ddd   6       sss
bbb-7       7       sss
所以我写代码如下,我想把dt1和dt2加入到dt中

    DataTable dt = new DataTable();
    dt.Columns.Add("TEST2");
    dt.Columns.Add("TEST3");
    dt.Columns.Add("TEST7");
    var result = from A1 in dt1.AsEnumerable()
                 join
                    A2 in dt2.AsEnumerable()
                 on
                    A1.Field<string>("TEST2") equals (A2.Field<string>("TEST2") + "-" + A2.Field<string>("TEST5") + (A2.Field<string>("TEST6") == string.Empty ? "-" : string.Empty) + A2.Field<string>("TEST6"))
                 select new dt.LoadDataRow(new object[] { A1.Field<string>("TEST2"), A1.Field<string>("TEST3"), A2.Field<string>("TEST7") }, false);
    result.CopyToDataTable();
DataTable dt=newdatatable();
dt.列添加(“测试2”);
dt.列添加(“测试3”);
dt.列添加(“测试7”);
var结果=来自dt1中的A1.AsEnumerable()
参加
dt2中的A2.AsEnumerable()
在…上
A1.字段(“TEST2”)等于(A2.字段(“TEST2”)+“-”+A2.字段(“TEST5”)+(A2.字段(“TEST6”)==string.Empty?”-“:string.Empty)+A2.字段(“TEST6”))
选择new dt.LoadDataRow(新对象[]{A1.Field(“TEST2”)、A1.Field(“TEST3”)、A2.Field(“TEST7”)},false);
result.CopyToDataTable();
但它不起作用~ 此外,我想更改TEST3和TEST7的列,TEST3将命名为X1,TEST3将命名为X5,因此最新一行的代码应该是

选择new dt.LoadDataRow(新对象[]{A1.Field(“TEST2”),X1=A1.Field(“TEST3”),X5=A2.Field(“TEST7”)},false)


这是另一个问题…我应该怎么做???

而不是
LoadDataRow
+
CopyToDataTable
方法我总是更喜欢简单的
foreach
方法,在查询中添加这些行。这一点更加明确,而且不依赖于副作用

您可以在字符串上进行连接,并将两行都放在匿名类型中:

var query = from r1 in dt1.AsEnumerable()
            join r2 in dt2.AsEnumerable()
            on r1.Field<string>("TEST2")
            equals string.Format("{0}-{1}-{2}"
                    , r2.Field<string>("TEST2")
                    , r2.Field<string>("TEST5")
                    , r2.Field<string>("TEST6"))
            select new { r1, r2 };

foreach (var bothRows in query)
{
    DataRow addedRow = dt.Rows.Add();
    addedRow.SetField("TEST2", bothRows.r1.Field<string>("TEST2"));
    addedRow.SetField("TEST3", bothRows.r2.Field<string>("TEST3"));
    addedRow.SetField("TEST7", bothRows.r2.Field<string>("TEST7"));
}
var query=来自dt1.AsEnumerable()中的r1
将r2加入dt2.AsEnumerable()中
关于r1.字段(“TEST2”)
等于string.Format(“{0}-{1}-{2}”
,r2.字段(“TEST2”)
,r2.字段(“TEST5”)
,r2.字段(“TEST6”))
选择新的{r1,r2};
foreach(查询中的变量bothRows)
{
DataRow addedRow=dt.Rows.Add();
addedRow.SetField(“TEST2”,bothRows.r1.Field(“TEST2”);
addedRow.SetField(“TEST3”,bothRows.r2.Field(“TEST3”);
addedRow.SetField(“TEST7”,bothRows.r2.Field(“TEST7”);
}

在internet上,您可以找到一个非常有用的功能,名为LinqToDataTable(附在下面),通过它,您可以将任何查询LINQ转换为DataTable,保留查询产生的数据类型。

公共数据表LINQTODatable(IEnumerable varlist)
{
DataTable dtReturn=新DataTable();
PropertyInfo[]oProps=null;
if(varlist==null)返回dtReturn;
foreach(varlist中的T rec)
{
//使用反射来获取属性名,创建表,只有第一次,其他人会跟随
if(oProps==null)
{
oProps=((Type)rec.GetType()).GetProperties();
foreach(oProps中的属性信息pi)
{
类型colType=pi.PropertyType;
if((colType.IsGenericType)&&(colType.GetGenericTypeDefinition()==typeof(null)))
{
colType=colType.GetGenericArguments()[0];
}
dtReturn.Columns.Add(新数据列(pi.Name,colType));
}
}
DataRow dr=dtReturn.NewRow();
foreach(oProps中的属性信息pi)
{
dr[pi.Name]=pi.GetValue(rec,null)==null?DBNull.Value:pi.GetValue
(rec,空);
}
dtReturn.Rows.Add(dr);
}
返回数据返回;
}

应轻松调用该函数:

var result=(来自dt1.AsEnumerable()中的A1)
参加
dt2中的A2.AsEnumerable()
在…上
A1.字段(“TEST2”)等于(A2.字段(“TEST2”)+“-”+A2.字段(“TEST5”)+(A2.字段(“TEST6”)==string.Empty?”-“:string.Empty)+A2.字段(“TEST6”))
选择新{
TEST2=A1.字段(“TEST2”),
x1=A1.字段(“测试3”),
x2=A2.字段(“测试7”)
});
DataTable dtFinal=LINQToDataTable(结果);
var query = from r1 in dt1.AsEnumerable()
            join r2 in dt2.AsEnumerable()
            on r1.Field<string>("TEST2")
            equals string.Format("{0}-{1}-{2}"
                    , r2.Field<string>("TEST2")
                    , r2.Field<string>("TEST5")
                    , r2.Field<string>("TEST6"))
            select new { r1, r2 };

foreach (var bothRows in query)
{
    DataRow addedRow = dt.Rows.Add();
    addedRow.SetField("TEST2", bothRows.r1.Field<string>("TEST2"));
    addedRow.SetField("TEST3", bothRows.r2.Field<string>("TEST3"));
    addedRow.SetField("TEST7", bothRows.r2.Field<string>("TEST7"));
}
 public DataTable LINQToDataTable<T>(IEnumerable<T> varlist)
        {
            DataTable dtReturn = new DataTable();
            PropertyInfo[] oProps = null;

            if (varlist == null) return dtReturn;

            foreach (T rec in varlist)
            {
                // Use reflection to get property names, to create table, Only first time, others will follow 
                if (oProps == null)
                {
                    oProps = ((Type)rec.GetType()).GetProperties();
                    foreach (PropertyInfo pi in oProps)
                    {
                        Type colType = pi.PropertyType;

                        if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>)))
                        {
                            colType = colType.GetGenericArguments()[0];
                        }

                        dtReturn.Columns.Add(new DataColumn(pi.Name, colType));
                    }
                }
                DataRow dr = dtReturn.NewRow();
                foreach (PropertyInfo pi in oProps)
                {
                    dr[pi.Name] = pi.GetValue(rec, null) == null ? DBNull.Value : pi.GetValue
                    (rec, null);
                }
                dtReturn.Rows.Add(dr);
            }
            return dtReturn;
        }
var result = (from A1 in dt1.AsEnumerable()
                          join
                             A2 in dt2.AsEnumerable()
                          on
                             A1.Field<string>("TEST2") equals (A2.Field<string>("TEST2") + "-" + A2.Field<string>("TEST5") + (A2.Field<string>("TEST6") == string.Empty ? "-" : string.Empty) + A2.Field<string>("TEST6"))
                          select new { 
                                TEST2 = A1.Field<string>("TEST2"), 
                                x1 = A1.Field<string>("TEST3"), 
                                x2 = A2.Field<string>("TEST7")
                          });

            DataTable dtFinal = LINQToDataTable(result);