1

I am doing project in ASP.NET Core MVC with Entity Framework Core.

I have two databases as contexts and I need to push to index this SQL:

SELECT 
    * 
FROM 
    db1.table1 AS tpt
JOIN 
    db2.table1 AS ta ON tpt.cIBAN = ta.cIBAN
JOIN
    db2.table2 AS tpa ON ta.nAccountID = tpa.nAccountID 
JOIN
    db2.table3 AS tc ON tc.nClientID = ta.nAccountID
WHERE
    ta.lActive = 1;

What I made so far is this

var query = await (from tpt in context1.table1
                   join ta in context2.table1 on tpt.CIban equals ta.CIban
                   join tpa in context2.table2 on ta.NAccountId equals tpa.NAccountId
                   join tc in context2.table3 on ta.NAccountId equals tc.NClientId
                   where ta.LActive == true
                   select new
                        {
                            tpt.DRegister,
                            tc.CNameOnPaymentCard,
                            tc.NClientId,
                            tpt.CIban,
                            tpt.CCurrency,
                            ta.NCurrency,
                            tpt.DValidityFrom,
                            tpt.DValidityTo,
                            tpt.CNote
                        }).ToListAsync();

However this will not work as I can not use query on two contexts at the same time.

Would really appreciate any help. Thanks, it bothers me for some time now....

EDIT:

I fixed the problem by splitting query into two LINQ statements returning lists and then concatenating two lists into one list of class. Not best solution, its hideous and slow. However, its working.

Solution:

var x = context1.table1.ToList();
var y = (from ta in context2.table1
                           join tc in context.table2 on ta.NAccountId 
                           equals tc.NClientId
                           where ta.LActive == true
                           select new {
                                thingsI_NeededToList
                                ...
                           }).ToList();

var xy = from table1 in y
         join table2 in x on table1.CIban equals table2.CIban
         select new ClassINeededToPass
         {
         ClassParameter = table1.parameter
         ...
         };
Stoky
  • 21
  • 1
  • 4
  • Did you try without the await? Why can't you use two contexts at same time? Why do you need to do this Async? – jdweng Feb 04 '20 at 12:18
  • This is what i get when i try to compile it: InvalidOperationException: Cannot use multiple DbContext instances within a single query execution. Ensure the query uses a single context instance. – Stoky Feb 04 '20 at 12:21
  • What type database are you using? It sounds like the database is not multi-user so you can only make one connection at a time. See following : https://stackoverflow.com/questions/10585478/one-dbcontext-per-web-request-why – jdweng Feb 04 '20 at 12:37
  • Windows Server 2016 Standard, its Microsoft sql server, main issue is i have all i need in context1.table1 that i work with then, i just need additional info in each row that i try to join At this point i am literally desprate. – Stoky Feb 04 '20 at 12:46
  • @Stoky contexts aren't databases or tables. DbSets are entities, not tables. What you ask is a) not possible and b) misuse of the ORM. Why are you using joins in the first place, and why multiple contexts? – Panagiotis Kanavos Feb 04 '20 at 12:53
  • @Stoky a DbContext should contain all the entities needed for a *specific* scenario. There's nothing wrong with having multiple contexts to server multiple scenarios, or having entities from different contexts map to the same table. If you find that some of the entities you need are in one context and some in another, it means that neither of them is good for the job at hand – Panagiotis Kanavos Feb 04 '20 at 12:55
  • Main problem is, i never worked with entityframework or with asp.net core MVC at all, all i knew was some magic in c# and .net. They put me to remake project that i knew nothing about so i just tried my best to put it together and now it is all falling apart. :( I have no idea what to do now. – Stoky Feb 04 '20 at 12:57
  • OK, you could take a step back and approach this from another angle. How about a stored procedure on the SQL Server. Execute this (code side) with a connection that has access to both DBs. I'm also a big fan of Dapper which is a light-weight ORM. You could even run your initial SQL easily with this and skip the stored procedure. My point is - there are probably a few ways to approach this. All is not lost. – scgough Feb 04 '20 at 13:07
  • @Stoky that's no solution at all. You loaded everything in the client, and joined them there. That's a *lot* slower than executing the actual query. You *don't* need to do any of that. Use Dapper and map the query's results to your objects, or create a view and map your objects to that query. What you did will cause serious problems when deployed to production. Imagine loading 100K rows from Table1 – Panagiotis Kanavos Feb 05 '20 at 09:09
  • @Stoky ORMs and LINQ aren't replacements for SQL. If you find yourself using JOINs, you're probably doing something wrong. A *proper* use of EF Core would be to have entities on the same context that map to those tables, with relations between them. The ORM would generate the JOINs, not the developer. If you don't need those entities for other reasons though, you shouldn't add them just for this query. Map to the view – Panagiotis Kanavos Feb 05 '20 at 09:10
  • @PanagiotisKanavos thank you very much for explanation. I am now more aware of mistakes i made. However i am in hurry to finish this, but i plan to fix this in future and redo it in, as you said view or with stored procedure. Its just fastest solution i came up with and i do not have time to fix it now. – Stoky Feb 05 '20 at 09:26

0 Answers0