-3

Using Dapper and LINQ I am able to get the data from two different databases. See the code below.

//Get Person details from Database 1 and populate the Model.
string sql1 = "Select * from dbo.person p left join dbo.address a on p.id = a.id";
var person = connection.Query<Person>(sql1);

//Get Employee details from Database 2 and populate the Model.     
string sql2 = "Select * from dbo.Employee";//I want to AVOID this, as it will fetch all the records.
var employee = connection.Query<Employee>(sql2);

//Use LINQ to get the desired result 
var res = from p in person
          join e in employee 
          on p.emp_id equals e.emp_id into prsnemp
          from pe in prsnemp.DefaultIfEmpty()
          select new 
            {
                Emp_Name = p.emp_name,
                Emp_Salary = pe?.emp_salary ?? string.Empty
            };
        

I want to avoid getting all the rows from Employee table and only get what is really necessary.


One solution is to create a synonym and put it in Database 1, so I could basically have something like the following

string finalSql = "Select p.emp_name, e.emp_salary from dbo.person p 
LEFT JOIN dbo.address a on p.id = a.id
LEFT JOIN dbo.employee e on e.id = p.id";

var result = connection.QueryAsync<EmployeePerson>(finalSql);

but I do not want to have synonyms either.

Thoughts?


Update - 1 I looked into the provided post and its answer I do not think it is going to work in my case, for two reasons.

  1. We will eventually move to the cloud. I wouldn't want to devise a solution that cross-references multiple databases and then runs into issues as others have asked in many posts, e.g. here.
  2. I also wouldn't want to add another task to our architect's plate to figure out how to make the cross-database query work, if I could find another way.

As of now I have a way forward to fetch the data from another database by passing a list of IDs, but this only works when INNER JOIN is in play, I do not know how to achieve the same for LEFT JOIN, unless of course I first get all the data from another database's table and then use LINQ's DefaultIfEmpty() method.

Vivek Shukla
  • 767
  • 6
  • 21
  • 1
    Create a CTE with a list of `p.empId` and join with Employee, or create an array of int `p.empId` and add them as an `IN` clause on 2nd query – Max Aug 26 '23 at 10:31
  • I should have mentioned this in the post but I thought about the or part too. Did not quite follow the CTE part of your comment. – Vivek Shukla Aug 26 '23 at 14:10
  • Why don't you just use three part naming `LEFT JOIN Database2.dbo.employee e on e.id = p.id` – Charlieface Aug 26 '23 at 21:17
  • I have to look into it but I thought I can not as we have APIs set up that would fetch the data from another database. – Vivek Shukla Aug 26 '23 at 23:04
  • @Max - what you have suggested to pass on a list of ids won’t work right, as I am trying to achieve left join. – Vivek Shukla Aug 27 '23 at 13:20
  • @Charlieface - could you see my updated post. – Vivek Shukla Aug 28 '23 at 16:37
  • @Max - I hope the updates help you to help me? – Vivek Shukla Aug 28 '23 at 16:37
  • It appears you've exhausted all available options. But your basic expectation that you can "avoid getting all the rows from Employee table" isn't realistic anyway. Even with databases on the same server the querying proces has to fetch all data from the other database. The optimizer can't handle two databases at the same time (one is hard enough). Maybe this will help you to reevaluate the options mentioned so far. – Gert Arnold Aug 28 '23 at 18:28
  • @GertArnold Thank you for the response. May I also request you to vote to reopen my question – Vivek Shukla Aug 28 '23 at 18:31
  • Well, I think the question can't be answered. People propose options, but none of them seem to fit the bill for you. Basically the answer is: can't be done. This would require a discussion thread, but that doesn't fit in Stack Overflow's format. – Gert Arnold Aug 28 '23 at 18:41
  • Also, the question might just as well have been closed as needing more details, because it's not clear why you need this query. The most obvious, and "API-able" solution would be to get Employee data one by one as and when needed. – Gert Arnold Aug 28 '23 at 18:46
  • @GertArnold - let's see if I interpreted your feedback right. Would I be correct in thinking that I might be able to achieve performance gains if I pass a list of IDs to the other table (other being - residing in another database) and receive a list of records instead of what `querying process` is forced to do i.e. it has to first load the entire records of the other table. in my case, my two APIs are responsible for CRUD operations, once I get the result, I could use LINQ to form a result. – Vivek Shukla Aug 28 '23 at 18:48
  • Sorry, I'm not going to discuss this any further here. Also because [this](https://dba.stackexchange.com/a/75360/81026) contradicts what I said above. It's too easy to make false claims in a case as broad as this one. – Gert Arnold Aug 28 '23 at 18:53
  • @GertArnold - Thank you so much. I understand. – Vivek Shukla Aug 28 '23 at 19:14
  • The issues you point out re cross-database queries (cloud etc) still remain, and the only solution to them is to do what you should have done in the first place: move the tables into the same DB. – Charlieface Aug 28 '23 at 19:32
  • yeah or have a copy of the table(cached) and use some sort of scheduler to periodically synchronize the tables. – Vivek Shukla Aug 28 '23 at 20:19

0 Answers0