C# 具有未知数据类型的LINQ的.Union()
我需要从不同的数据库获取数据,然后将这两个数据集合并到一个IQueryable集合中 数据库1数据示例:C# 具有未知数据类型的LINQ的.Union(),c#,sql-server,linq,C#,Sql Server,Linq,我需要从不同的数据库获取数据,然后将这两个数据集合并到一个IQueryable集合中 数据库1数据示例: -- SOLUTION #1 [ID] [int], [Name] [nvachar](50), [ExpirationDate] [datetime], [Users] [int] -- SOLUTOIN #1 [ID] [int], [Name] [nvarchar](50), [Users] [int] 数据库2数据示例: -- SOLUTION #1 [ID] [int], [N
-- SOLUTION #1
[ID] [int],
[Name] [nvachar](50),
[ExpirationDate] [datetime],
[Users] [int]
-- SOLUTOIN #1
[ID] [int],
[Name] [nvarchar](50),
[Users] [int]
数据库2数据示例:
-- SOLUTION #1
[ID] [int],
[Name] [nvachar](50),
[ExpirationDate] [datetime],
[Users] [int]
-- SOLUTOIN #1
[ID] [int],
[Name] [nvarchar](50),
[Users] [int]
如您所见,database 2的解决方案没有属性ExpirationDate,这给我在进行联合时带来了一些问题
我尝试了以下方法:
.Union(from solution2 in db2.Solutions
select new{
Id = solution2.ID,
Name = solution2.Name,
ExpirationDate = (DateTime?) solution2.ExpirationDate,
Users = solution2.Users
});
但不幸的是,这不起作用。调用此函数时,我得到以下异常:
对象引用未设置为对象的实例
我想这是因为我设置了ExpirationDate=DateTime?空
我还尝试从SQL视图中获取数据,这是一个db2示例,因为db1有点不言自明
然后,将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
我不太确定如何完成这一陈述。有什么想法吗?尝试以这种方式修改第一个查询:
// ...
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;}
}
}
在第二种情况下,请尝试:
CREATE VIEW [dbo].[v_Solutions]
AS SELECT s.ID,
s.Name,
CAST(NULL as DateTime) AS [ExpirationDate],
s.Users
FROM Solution
LINQ 2 SQL和EF不支持从多个DB上下文中提取查询。显然,您甚至触发了一个bug,导致了一个NullReferenceException 您可以在内存中执行并集:
db1.SomeTable.AsEnumerable().Union(db2.SomeTable.AsEnumerable())
如果希望在数据库中执行联合,则需要使用原始SQL,或将某些表映射到DBML中的另一个数据库,或使用表值函数或视图。我完全搞砸了。我的db1和db2实例一直是空的。我的代码中有些东西不起作用,尽管它应该起作用。我现在有另一个问题,但是NullReferenceException已经不存在了。如果您使用EF对两个DBs进行查询,我假设您需要在内存中进行联合。因此,将一个AsEnumerable放在Union之前,另一个放在Union内部查询的末尾。确保solution1或solution2本身不为null。。。。例如,从db1中的solution1以这种方式跳过它们。Solutions其中solution1!=null选择new…..仅将null作为[ExpirationDate]可能无法推断正确的类型,因此将null强制转换为datetime可能会在视图中起作用?@M.kazemAkhgary我的解决方案1实际上为null。我想知道为什么,但至少我发现了这个问题。如果在你的集合中应该有null,那么就不用担心你可以告诉他们在哪里。但是,如果你的集合中不希望有空项,就不要用where命令它们。尝试找出导致空元素的主要问题…不应该将ADO.Net的DBNull与Linq SQL提供程序混合使用。它应该为您在DBNull和null之间进行转换。@juharr这无论如何都不起作用,因为System.DBNull.Value与第一个select语句不对应。这个答案很可能会起作用,因为该类型现在被识别为Datetime?。但我的问题是,我的条目为null,引发了NullReferenceException。我的问题与这个问题的主题不同,但我不能使用AsEnumerable。检查我的退货类型function@Detilium您必须将返回类型更改为IEnumerable,并且确实应该使用自定义类将值投影到其中,这样您就可以使用类似IEnumerable的内容进行强类型。我向您展示的代码只是一个简单的操作示例,与我的实际代码相比,这算不了什么。我需要它是IQueryable,并且我不会更改返回类型。您不能跨上下文、句点进行查询。也许你只需要一个假的问号?对最终结果调用AsQueryable。在不知道您想要实现什么以及为什么有这些限制的情况下,很难推荐特定的解决方案。我试图重新创建您的案例,请参阅更新的答案。我想知道我们遗漏了什么。你应该在问题中添加这些信息。但这并不重要,因为这种方法无法满足您的需求。正如你所说,你只会得到另一个不同的错误。