LINQPad, using multiple datacontexts

C#LinqLinq to-SqlDatacontextLinqpad

C# Problem Overview


I am often comparing data in tables in different databases. These databases do not have the same schema. In TSQL, I can reference them with the DB>user>table structure (DB1.dbo.Stores, DB2.dbo.OtherPlaces) to pull the data for comparison. I like the idea of LINQPad quite a bit, but I just can't seem to easily pull data from two different data contexts within the same set of statements.

I've seen people suggest simply changing the connection string to pull the data from the other source into the current schema but, as I mentioned, this will not do. Did I just skip a page in the FAQ? This seems a fairly routine procedure to be unavailable to me.

In the "easy" world, I'd love to be able to simply reference the typed datacontext that LINQPad creates. Then I could simply:

DB1DataContext db1 = new DB1DataContext();
DB2DataContext db2 = new DB2DataContext();

And work from there.

C# Solutions


Solution 1 - C#

Update: it's now possible to do cross-database SQL Server queries in LINQPad (from LINQPad v4.31, with a LINQPad Premium license). To use this feature, hold down the Control key while dragging databases from the Schema Explorer to the query window.

It's also possible to query linked servers (that you've linked by calling sp_add_linkedserver). To do this:

  1. Add a new LINQ to SQL connection.
  2. Choose Specify New or Existing Database and choose the primary database you want to query.
  3. Click the Include Additional Databases checkbox and pick the linked server(s) from the list.

Solution 2 - C#

Keep in mind that you can always create another context on your own.

public FooEntities GetFooContext()
{
   var entityBuilder = new EntityConnectionStringBuilder	  	
               {	  	
                    Provider = "Devart.Data.Oracle",	  	
                    ProviderConnectionString = "User Id=foo;Password=foo;Data Source=Foo.World;Connect Mode=Default;Direct=false",
  	                Metadata = @"D:\FooModel.csdl|D:\FooModel.ssdl|D:\FooModel.msl"	  	
                };

	return new FooEntities(entityBuilder.ToString());
}

Solution 3 - C#

You can instantiate as many contexts as you like to disparate SQL instances and execute pseudo cross database joins, copy data, etc. Note, joins across contexts are performed locally so you must call ToList(), ToArray(), etc to execute the queries using their respective data sources individually before joining. In other words if you "inner" join 10 rows from DB1.TABLE1 with 20 rows from DB2.TABLE2, both sets (all 30 rows) must be pulled into memory on your local machine before Linq performs the join and returns the related/intersecting set (20 rows max per example).

//EF6 context not selected in Linqpad Connection dropdown
var remoteContext = new YourContext();
remoteContext.Database.Connection.ConnectionString = "Server=[SERVER];Database="
+ "[DATABASE];Trusted_Connection=false;User ID=[SQLAUTHUSERID];Password=" 
+ "[SQLAUTHPASSWORD];Encrypt=True;";
remoteContext.Database.Connection.Open();
var DB1 = new Repository(remoteContext);

//EF6 connection to remote database
var remote = DB1.GetAll<Table1>()
	.Where(x=>x.Id==123)
	//note...depending on the default Linqpad connection you may get 
    //"EntityWrapperWithoutRelationships" results for 
	//results that include a complex type.  you can use a Select() projection 
    //to specify only simple type columns
	.Select(x=>new { x.Col1, x.Col1, etc... })
	.Take(1)
	.ToList().Dump();  // you must execute query by calling ToList(), ToArray(),
        	  // etc before joining


//Linq-to-SQL default connection selected in Linqpad Connection dropdown
Table2.Where(x=>x.Id = 123)
	.ToList() // you must execute query by calling ToList(), ToArray(),
        	  // etc before joining
	.Join(remote, a=> a.d, b=> (short?)b.Id, (a,b)=>new{b.Col1, b.Col2, a.Col1})
	.Dump();
		
localContext.Database.Connection.Close();
localContext = null;

Solution 4 - C#

I do not think you are able to do this. See this LinqPad request.

However, you could build multiple dbml files in a separate dll and reference them in LinqPad.

Solution 5 - C#

Drag-and-drop approach: hold down the Ctrl key while dragging additional databases from the Schema Explorer to the query editor.

Use case:

//Access Northwind

var ID = new Guid("107cc232-0319-4cbe-b137-184c82ac6e12");

LotsOfData.Where(d => d.Id == ID).Dump();

//Access Northwind_v2

this.NORTHWIND_V2.LotsOfData.Where(d => d.Id == ID).Dump();

Solution 6 - C#

Multiple databases are as far as I know only available in the "paid" version of LinqPad (what I wrote applies to LinqPad 6 Premium).

For more details, see this answer in StackOverflow (section "Multiple database support").

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionScottView Question on Stackoverflow
Solution 1 - C#Joe AlbahariView Answer on Stackoverflow
Solution 2 - C#ChristophView Answer on Stackoverflow
Solution 3 - C#AdamView Answer on Stackoverflow
Solution 4 - C#Jeremy RobertsView Answer on Stackoverflow
Solution 5 - C#Brian Løkke BorgView Answer on Stackoverflow
Solution 6 - C#MattView Answer on Stackoverflow