Reputation: 3034
I need to get data from to different databases and then combine these two data sets into a single IQueryable
collection.
Database #1 example of data:
-- SOLUTION #1
[ID] [int],
[Name] [nvachar](50),
[ExpirationDate] [datetime],
[Users] [int]
Databse #2 example of data:
-- SOLUTOIN #1
[ID] [int],
[Name] [nvarchar](50),
[Users] [int]
As you can see, the solution from database #2 doesn't have the attribute ExpirationDate
, which gives me some problems when doing the Union()
.
I have tried the following:
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
});
}
But unfortunately, this doesn't work. When calling this, I get the following exception:
Object reference not set to an instance of an object.
I suppose that this is because I set the ExpirationDate = (DateTime?) null
.
I have also tried to get the data from SQL views, like so (this is an example of db2
as db1
is kind off self explanatory)
CREATE VIEW [dbo].[v_Solutions]
AS SELECT s.ID,
s.Name,
null AS [ExpirationDate],
s.Users
FROM Solution
An then altered the LINQ select new
statement to the following:
.Union(from solution2 in db2.Solutions
select new{
Id = solution2.ID,
Name = solution2.Name,
ExpirationDate = (DateTime?) solution2.ExpirationDate,
Users = solution2.Users
});
But doing this gives me a compile error:
Cannot convert type 'int?' to 'System.DateTime?'
Though the data in solution2.ExpirationDate
should just be null
.
I'm not quite sure how to complete this statement. Any ideas?
Upvotes: 2
Views: 673
Reputation: 3034
I completely messed up. My instances of db1
and db2
were null all along. Something in my code wasn't working though it should. I have another problem now, but the NullReferenceException
is gone.
Upvotes: 0
Reputation: 1684
Try to modify 1st query this way :
// ...
ExpirationDate = (DateTime?)solution1.ExpirationDate,
UPDATE:
I tried to recreate your case, this seems to work :
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;}
}
}
Upvotes: 0
Reputation: 24144
In the second case try:
CREATE VIEW [dbo].[v_Solutions]
AS SELECT s.ID,
s.Name,
CAST(NULL as DateTime) AS [ExpirationDate],
s.Users
FROM Solution
Upvotes: 0
Reputation: 171178
LINQ 2 SQL and EF do not support queries pulling from multiple DB contexts. Apparently, you are even triggering a bug doing that causing a NullReferenceException
.
You can perform the union in memory:
db1.SomeTable.AsEnumerable().Union(db2.SomeTable.AsEnumerable())
If you want the union executed in the database you need to use raw SQL, or map some table to another database in the DBML or use table valued functions or views.
Upvotes: 3