使用LINQ从两个表中获取数据而无需任何列键

时间:2019-07-13 15:37:10

标签: c# linq linq-to-sql

我在c#中有两个列表。这两个列表具有不同的类型(不同的对象)。 我想使用LINQ从这两个列表中获取数据到新的第三列表中。 第三个列表具有所有必需的属性,可以存储两个列表中的数据。 这是我的两个来源清单

var posts = new List<GeneralPost>()
            {
                new GeneralPost(){PostID=1, PostDescription = "Post 1" , PostTime = DateTime.Now.AddDays(-1) },
                new GeneralPost(){PostID=2, PostDescription = "Post 2" , PostTime = DateTime.Now.AddDays(-2)},
                new GeneralPost(){PostID=3, PostDescription = "Post 3" , PostTime = DateTime.Now.AddDays(-3)},
                new GeneralPost(){PostID=4, PostDescription = "Post 4" , PostTime = DateTime.Now.AddDays(-4)},

        };

var products = new List<EnquiryProduct>()
            {
                new EnquiryProduct(){BusinessId=1, ProductDescription="ProductDesc 1", CreatedDate = DateTime.Now.AddDays(1) },
                new EnquiryProduct(){BusinessId=2, ProductDescription="ProductDesc 2", CreatedDate = DateTime.Now.AddDays(0) },
                new EnquiryProduct(){BusinessId=3, ProductDescription="ProductDesc 3", CreatedDate = DateTime.Now.AddDays(-1) },
            };

我已经尝试过-

 var total = (from p in posts.DefaultIfEmpty()
                         from pro in products.DefaultIfEmpty()
                         select new
                         {
                             PostId = p.PostID,
                             ProductId = pro.BusinessId,
                             PostDes = p.PostDescription,
                             ProductDes = pro.ProductDescription
                         }).ToList();

这是我的输出期望-

PostId  ProductId   PostDescrition  ProductDescriptin
1       null        Post 1      null
2       null        Post 2      null
3       null        Post 3      null
4       null        Post 4      null
null    1           null        ProductDesc 1
null    2           null        ProductDesc 2
null    3           null        ProductDesc 3

3 个答案:

答案 0 :(得分:0)

基本上,这是to列表的串联。

您可以使用Concat从两个带有“单线”的列表中将数据选择到新对象中。

我在这里使用匿名,但是您也可以使用显式类型的类。

posts.Select(c => new { 
         PostId = c.PostID,
         ProductId = null,
         PostDescrition = c.PostDescription,
         ProductDescription = null}).
      Concat(products.Select(c => new {
         PostId = null,
         ProductId = c.ProductId,
         PostDescrition = null,
         ProductDescription = c.ProductDescription}));

请注意:不允许postsproductsnull。它们可能为空,但null会导致null引用异常。


另一个注意事项:还有其他选项可以在特定字段上join,或创建union(这是Concat的连接版本)。这些是相关的,但不相似。

答案 1 :(得分:0)

您可以这样做:

    var postTemp = (from p in posts
                        let PostId = p.PostID
                        let ProductId = ""
                        let PostDes = p.PostDescription
                        let ProductDes = ""
                        select new {PostId, ProductId, PostDes, ProductDes }
                        ).ToList();

        var productsTemp = (from p in products
                            let PostId = ""
                            let ProductId = p.BusinessId
                            let PostDes = ""
                            let ProductDes = p.ProductDescription
                            select new{ PostId, ProductId, PostDes,ProductDes }).ToList();

        var allResidents = postTemp.Union<object>(productsTemp).ToList();

输出将为

https://i.stack.imgur.com/7YyfJ.png

答案 2 :(得分:0)

如果您需要组合具有不同类型的列表,则需要将两个列表都强制转换为object,然后可以concat对其进行转换。

因此,对于您的total变量,您需要改为执行以下行:

var total = posts.ToList<object>().Concat(products.ToList<object>()).ToList();

然后您可以迭代总列表,但是您还需要将它们重铸为它们的原始类型以获取它们的值(更易于处理)。

这是一个简单的示例:

    foreach (var item in total)
    {
        if(item.GetType() == typeof(GeneralPost))
        {
            var record = (item as GeneralPost);
            Console.WriteLine($"{record.PostID}\tnull\t{record.PostDescription}\tnull");
        }
        else
        {
            var record = (item as EnquiryProduct);
            Console.WriteLine($"null\t{record.BusinessId}\tnull\t{record.ProductDescription}");


        }

    }

以上示例的输出为:

1       null    Post 1  null
2       null    Post 2  null
3       null    Post 3  null
4       null    Post 4  null
null    1       null    ProductDesc 1
null    2       null    ProductDesc 2
null    3       null    ProductDesc 3