LINQ的.Union()数据类型未知

时间:2016-06-02 12:37:24

标签: c# sql-server linq

我需要将数据从不同的数据库中获取,然后将这两个数据集合并到一个IQueryable集合中。

数据库#1数据示例:

-- SOLUTION #1
[ID] [int],
[Name] [nvachar](50),
[ExpirationDate] [datetime],
[Users] [int]

数据库#2数据示例:

-- SOLUTOIN #1
[ID] [int],
[Name] [nvarchar](50),
[Users] [int]

正如您所看到的,数据库#2的解决方案没有属性ExpirationDate,这在执行Union()时会给我一些问题。

我尝试了以下内容:

public static IQueryable GetAll()
{
    var list = (from solution1 in db1.Solutions
            select new
            {
                Id = solution1.ID,
                Name = solution1.Name,
                ExpirationDate = solution1.ExpirationDate,
                Users = solution1.Users
            })
        .Union(from solution2 in db2.Solutions
            select new{
                Id = solution2.ID,
                Name = solution2.Name,
                ExpirationDate = (DateTime?) null,
                Users = solution2.Users        
            });
}

但遗憾的是,这并不奏效。调用它时,我得到以下异常:

  

对象引用未设置为对象的实例。

我想这是因为我设置了ExpirationDate = (DateTime?) null

我也尝试从SQL视图中获取数据,如此(这是db2的示例,因为db1有点不言自明

CREATE VIEW [dbo].[v_Solutions]
    AS SELECT s.ID,
        s.Name,
        null AS [ExpirationDate],
        s.Users
    FROM Solution

然后将LINQ select new语句更改为以下内容:

.Union(from solution2 in db2.Solutions
            select new{
                Id = solution2.ID,
                Name = solution2.Name,
                ExpirationDate = (DateTime?) solution2.ExpirationDate,
                Users = solution2.Users        
            });

但这样做会给我一个编译错误:

  

无法转换类型' int?'到' System.DateTime?'

虽然solution2.ExpirationDate中的数据应该只是null

我不太清楚如何完成这个陈述。有什么想法吗?

4 个答案:

答案 0 :(得分:3)

LINQ 2 SQL和EF不支持从多个DB上下文中提取查询。显然,你甚至会触发一个导致NullReferenceException的错误。

您可以在内存中执行联合:

db1.SomeTable.AsEnumerable().Union(db2.SomeTable.AsEnumerable())

如果要在数据库中执行union,则需要使用原始SQL,或将某些表映射到DBML中的另一个数据库,或使用表值函数或视图。

答案 1 :(得分:0)

尝试以这种方式修改第一个查询:

// ...
ExpirationDate = (DateTime?)solution1.ExpirationDate,

更新:

我试图重新创建你的案例,这似乎有效:

using System.Collections.Generic;
using System.Threading.Tasks;
using System.Data.Entity;
using System.Linq;  
using System;

public class Program
{
    public static void Main()
    {
        var itemsA = new[]{new ItemA {Name = "a", Date = DateTime.Now}};
        var itemsB = new[]{new ItemB {Name = "b" }};


        var list = (from solution1 in itemsA
            select new
            {
                Name = solution1.Name,
                Date = (DateTime?)solution1.Date
            })
        .Union(from solution2 in itemsB
            select new{
                Name = solution2.Name,
                Date = (DateTime?)null                
            });

        Console.WriteLine(list.Count());

    }
    public class ItemA
    {
        public string Name {get;set;}
        public DateTime Date {get;set;}
    }
    public class ItemB
    {
        public string Name {get;set;}

    }

}

答案 2 :(得分:0)

在第二种情况下尝试:

CREATE VIEW [dbo].[v_Solutions]
    AS SELECT s.ID,
        s.Name,
        CAST(NULL as DateTime)  AS [ExpirationDate],
        s.Users
    FROM Solution

答案 3 :(得分:0)

我完全搞砸了。我db1db2的实例一直都是null。我的代码中的某些东西虽然应该没有用。我现在有另一个问题,但NullReferenceException已经消失了。