将带有联接的 Linq-to-DataSet 查询的结果加载到数据表中

发布于 2024-08-13 15:39:21 字数 1522 浏览 2 评论 0原文

我有一个 Linq to dataset 查询,它连接两个表并从每个表中提取所需的参数。我需要将它们放入 DataTable 中以绑定到 DataGridView。我在 MSDN 上找到的执行此操作的示例是一个简单的示例来自单个表的单个值,但是当我尝试更改查询以遵循它时,我无法这样做。 CopyToDataTable() 方法要求将查询分配给 IEnumerable,但当我这样做时,我被告知需要显式转换;但转换在运行时失败,但有以下例外:

无法转换类型为“d__61`4[System.Data.DataRow,System.Data.DataRow,System.Int32,<>f__AnonymousType0`1[System.Int32]]”的对象 键入 'System.Collections.Generic.IEnumerable`1[System.Data.DataRow]'。

原始工作查询:

var query = MyDataSet.Table1.AsEnumerable().Join(MyDataSet.Table2.AsEnumerable(),
    table1 => table1.Field<Int32>("Table1_Id"),
    table2 => table2.Field<Int32>("Table1_Id"),
    (table1, table2) => new
    {
        Table1ID = table1.Field<Int32>("Table1_Id")
        //Other parameters commented out to simplify the example
    });

具有显式转换的非工作查询:

IEnumerable<DataRow> query = (IEnumerable<DataRow>)MyDataSet.Table1.AsEnumerable()
                                             .Join(MyDataSet.Table2.AsEnumerable(),
    table1 => table1.Field<Int32>("Table1_Id"),
    table2 => table2.Field<Int32>("Table1_Id"),
    (table1, table2) => new
    {
        Table1ID = table1.Field<Int32>("Table1_Id")
        //Other parameters commented out to simplify the example
    });

I have a Linq to dataset query that joins two tables and extracts the desired parameters from each. I need to get them into a DataTable to bind to a DataGridView. The example I found for doing this on MSDN is a trivial example taking a single value from a single table, but when I tried to change my query to follow it I was unable to do so. The CopyToDataTable() method requires that the query be assigned to a IEnumerable<DataRow>, but when I do so I'm told that an explicit cast is needed; but the cast fails at runtime with the exception:

Unable to cast object of type 'd__61`4[System.Data.DataRow,System.Data.DataRow,System.Int32,<>f__AnonymousType0`1[System.Int32]]'
to type
'System.Collections.Generic.IEnumerable`1[System.Data.DataRow]'.

Original working query:

var query = MyDataSet.Table1.AsEnumerable().Join(MyDataSet.Table2.AsEnumerable(),
    table1 => table1.Field<Int32>("Table1_Id"),
    table2 => table2.Field<Int32>("Table1_Id"),
    (table1, table2) => new
    {
        Table1ID = table1.Field<Int32>("Table1_Id")
        //Other parameters commented out to simplify the example
    });

Non-working query with explicit cast:

IEnumerable<DataRow> query = (IEnumerable<DataRow>)MyDataSet.Table1.AsEnumerable()
                                             .Join(MyDataSet.Table2.AsEnumerable(),
    table1 => table1.Field<Int32>("Table1_Id"),
    table2 => table2.Field<Int32>("Table1_Id"),
    (table1, table2) => new
    {
        Table1ID = table1.Field<Int32>("Table1_Id")
        //Other parameters commented out to simplify the example
    });

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

凑诗 2024-08-20 15:39:21

在这两种情况下,您都将创建一个新的“匿名类型”来存储结果。

要使第二个工作正常,您需要类似以下内容:

var query = ... => new DataRow() 
{
});

但这不起作用,因为 DataRow 没有公共构造函数并且无法以这种方式初始化。

因此,使用第一个并迭代结果(请注意,我在这里猜测了一点,并且您必须首先设置 table3 的列):

foreach (var row in query)
{
   var r = table3.NewRow();
   r["Table1ID"] = row.Table1ID;
   r["Table2ID"] = row.Table1ID;                
}

编辑:

 var query = ...;  // step 1

 query = query.ToList();  // add this,  step 2

 foreach(...) { }  // step 3

如果您分别对上述 3 个步骤进行计时,您可能会看到第 2 步花费的时间最多。

In both cases, you are creating a new 'anonymous type' to store the results.

To make the second one work, you would need something like:

var query = ... => new DataRow() 
{
});

except that is not going to work because DataRow has no public constructor and cannot be initialised this way.

So, use the first one and iterate over the results (note that I'm guessing a little here, and that you have to setup the columns for table3 first):

foreach (var row in query)
{
   var r = table3.NewRow();
   r["Table1ID"] = row.Table1ID;
   r["Table2ID"] = row.Table1ID;                
}

Edit:

 var query = ...;  // step 1

 query = query.ToList();  // add this,  step 2

 foreach(...) { }  // step 3

If you time the 3 steps above separately you will probably see that step 2 takes the most time.

厌味 2024-08-20 15:39:21

嗨,这是另一种方法。

        //I have created datatable Address having AddressID<int32>,Name-srting,LastName-string
        DataSet ds= new DataSet();
        ds.Tables["Address"].Rows.Add(new object[] { 1, "Priya", "Patel" });
        ds.Tables["Address"].Rows.Add(new object[] { 2, "Bunty", "Rayapati" });
        ds.Tables["Address"].Rows.Add(new object[] { 3, "Birva", "Parikh" });
        //i have created Datatable AddressType having AddressTypeID int32 and State- string
        ds.Tables["AddressType"].Rows.Add(new object[] { 1, "Virginia" });
        ds.Tables["AddressType"].Rows.Add(new object[] { 2, "Nebraska" });
        ds.Tables["AddressType"].Rows.Add(new object[] { 3, "Philadeplhia" });

        DataTable dt1 = ds.Address.CopyToDataTable(); 
        DataTable dt2 = ds.AddressType.CopyToDataTable();
        DataTable dt3 = new DataTable();

        var query = dt1.AsEnumerable().Join(dt2.AsEnumerable(),
            dmt1 => dmt1.Field<Int32>("AddressID"),
                dmt2 => dmt2.Field<Int32>("AddressTypeID"),
        (dmt1, dmt2) => new 
        {
            Table1ID = dmt1.Field<Int32>("AddressID")
            //Other parameters commented out to simplify the example
        });
        query.ToList();
        //FullAddress is my third Datatable is having AID
        foreach (var row in query)
        {
            var r = ds.FullAddress.NewRow();
            r["AID"] = row.Table1ID;
            ds.FullAddress.Rows.Add(r.ItemArray);

        }

Hi this is the other way to do it..

        //I have created datatable Address having AddressID<int32>,Name-srting,LastName-string
        DataSet ds= new DataSet();
        ds.Tables["Address"].Rows.Add(new object[] { 1, "Priya", "Patel" });
        ds.Tables["Address"].Rows.Add(new object[] { 2, "Bunty", "Rayapati" });
        ds.Tables["Address"].Rows.Add(new object[] { 3, "Birva", "Parikh" });
        //i have created Datatable AddressType having AddressTypeID int32 and State- string
        ds.Tables["AddressType"].Rows.Add(new object[] { 1, "Virginia" });
        ds.Tables["AddressType"].Rows.Add(new object[] { 2, "Nebraska" });
        ds.Tables["AddressType"].Rows.Add(new object[] { 3, "Philadeplhia" });

        DataTable dt1 = ds.Address.CopyToDataTable(); 
        DataTable dt2 = ds.AddressType.CopyToDataTable();
        DataTable dt3 = new DataTable();

        var query = dt1.AsEnumerable().Join(dt2.AsEnumerable(),
            dmt1 => dmt1.Field<Int32>("AddressID"),
                dmt2 => dmt2.Field<Int32>("AddressTypeID"),
        (dmt1, dmt2) => new 
        {
            Table1ID = dmt1.Field<Int32>("AddressID")
            //Other parameters commented out to simplify the example
        });
        query.ToList();
        //FullAddress is my third Datatable is having AID
        foreach (var row in query)
        {
            var r = ds.FullAddress.NewRow();
            r["AID"] = row.Table1ID;
            ds.FullAddress.Rows.Add(r.ItemArray);

        }
兰花执着 2024-08-20 15:39:21

我遇到了这样的错误,因为在 LINQ 查询中在许多连接语句之后,编译器创建连接所有模型的新类型

所以很难直接转换

,但它你知道结果只包含一个特定的模型,你可以再做一个步骤来帮助编译器转换它,那就是

MyListOfTypeIEnumerable.ToArray()

看看我的问题并 ToArray() 解决它

public static IList<Letter> GetDepartmentLetters(int departmentId)
    {
        IEnumerable<Letter> allDepartmentLetters = from allLetter in LetterService.GetAllLetters()
            join allUser in UserService.GetAllUsers() on allLetter.EmployeeID equals allUser.ID into usersGroub
            from user in usersGroub.DefaultIfEmpty()
            join allDepartment in DepartmentService.GetAllDepartments() on user.DepartmentID equals allDepartment.ID
            where allDepartment.ID == departmentId
            select allLetter;
        return allDepartmentLetters.ToArray();
    }

I was facing such error such error because after many joins statements in your LINQ query the compiler create new type that concatenate all your models

so so its hard to cast in directly

but it you know that the result contain only one specific Model you can do one more step to help the compiler to cast it which is

MyListOfTypeIEnumerable.ToArray()

take look at my problem and ToArray() solve it

public static IList<Letter> GetDepartmentLetters(int departmentId)
    {
        IEnumerable<Letter> allDepartmentLetters = from allLetter in LetterService.GetAllLetters()
            join allUser in UserService.GetAllUsers() on allLetter.EmployeeID equals allUser.ID into usersGroub
            from user in usersGroub.DefaultIfEmpty()
            join allDepartment in DepartmentService.GetAllDepartments() on user.DepartmentID equals allDepartment.ID
            where allDepartment.ID == departmentId
            select allLetter;
        return allDepartmentLetters.ToArray();
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文