LINQ Join Tables from Different Database or DataContext - c#

var possibleTPMs = (from ui in db1.Users
from org in db2.Orgs.Where(o => o.OrgId == ui.OrgId && !o.DeletedFlag).DefaultIfEmpty()
where !ui.DeletedFlag && ui.ActiveFlag && ui.OrgId == 1 && ui.UserId != 1
select new { ui.UserId, ui.LastName, ui.FirstName }).ToList();
Above is sample LINQ but having errors, How can I join these two tables that came from two different databases.

To join two 'tables' you simply join them with the below syntax. You shouldn't need any complex join using wheres
var possibleTPMs = (from ui in db1.Users
join org in db2.Orgs on ui.id equals org.id
select new { ui.UserId, ui.LastName, ui.FirstName }).ToList();

Related

Error: the specified linq expression contains references to queries that are associated with different context

I have this linq query that returns the revenue associated with every colorwaysid present within the given dates but it throws the SQLException:
the specified linq expression contains references to queries that are
associated with different context
using (var eshaktiDb = new eshaktiEntities())
{
using (var corpDb = new eshakti_corpEntities())
{
var queryResult =
from product in eshaktiDb.Products
join oivs in corpDb.OrderitemvalueSplits on product.ProductId equals oivs.Productid
join order in corpDb.Orders on oivs.Orderid equals order.OrderID
where product.ColorWaysId != null && order.CrDate >= fromDate && order.CrDate <= toDate
group oivs by product.ColorWaysId into g
select new ColorwayReportResponse
{
colorwayId = (int)g.Key,
revenue = (decimal)g.Sum(o => o.ActItemvalue + o.Custom)
};
return queryResult.ToList();
}
}
How to fix this ? Can somebody help me with the query that would fit in, also since the query involves two different databases, how can I get my desired result ?
I would separate this out into 2 separate queries starting with your corpDb:
var queryResult = (select * from corpDb.OrderitemvalueSplits join order in corpDb.Orders on oivs.Orderid equals order.OrderID).ToArray();
Then I would use perform the corresponding join afterwards in the other context.
var products = select * from product in eshaktiDb.Products join oivs in queryResult.OrderitemvalueSplits on product.ProductId equals oivs.Productid where product.ColorWaysId != null && order.CrDate >= fromDate && order.CrDate <= toDate
group oivs by product.ColorWaysId into g
select new ColorwayReportResponse
{
colorwayId = (int)g.Key,
revenue = (decimal)g.Sum(o => o.ActItemvalue + o.Custom)
};
There are other possible solutions to this issue here.
I'm not sure the above would work exactly in your code but generally you are not allowed to join within 2 separate contexts in Entity framework but you are allowed to pass arrays and other values between requests to accomplish the same task.

Structuring two conditional left outer joins into one query using LINQ, C#

Currently, I am executing two queries based upon whether w.Type is either 1 or 2. If w.Type is 1 we perform a join to the Issues table and if the Type is 2 we join to the TSubs table. I am trying to merge these queries into one.
var productIdOne = (from w in listAbandonedCarts
join i in Issues on w.ProductId equals i.Id
where w.Type == 1
select new { i.Title.Name }).ToList();
var productIdTwo = (from w in listAbandonedCarts
join ts in TSubs on w.ProductId equals ts.Id
where w.Type == 2
select new { ts.Title.Name }).ToList();
I am considering using two left outer joins based upon this SQL psuedo-code
SELECT*
FROM P_carts pc
LEFT OUTER tSubs ts on ts.id = pc.productid and pc.Type = 2
LEFT OUTER issues i on i.id = pc.productid and pc.Type = 1
So far i have some linq pseudo coded but i'm struggling to get the syntax correct for the two conditional joins
var listProducts = (from w in listAbandonedCarts
join i in Issues on w.ProductId equals i.Id into iN && w.ProductId == 1
from i in iN.DefaultIfEmpty()
join into ts in TSubs.....
The problem I'm struggling with is that this isn't a double left outer its two separate joins. My current error is that i cannot have w.ProductId after the equals because I'm out of scope of w at this point and can't figure out how to structure the linq statement. Any help would be much appreciated, thanks!
Give this a shot:
var productIds = (
from w in listAbandonedCarts
from i in Issues.Where(issue => issue.Id == w.ProductId && w.Type == 1).DefaultIfEmpty()
from t in TSubs.Where(tsub => tsub.Id == w.ProductId && w.Type == 2).DefaultIfEmpty()
select new {Name = (w.Type == 1 ? i.Title.Name : t.Title.Name)})
.ToList();
var listProducts = (from w in listAbandonedCarts
join i in Issues on w.ProductId equals i.Id && w.ProductId == 1 into iN
from i in iN.DefaultIfEmpty()
join into ts in TSubs on ts.id equals pc.productid into tsBag
from ts in tsBag.DefaultIfEmpty()
select new
{
// All columns you need
};
Please try the above linq. This sample code is not compiled nor tested. Please use this for reference purpose only.

How to join 3 tables with linq

I am trying to join 3 tables in a query with Linq to get data from all 3 tables. Below is an image of the table schemes:
The query should select: SewagePlantName, CompanyName and Duty
In addition I need to restricts the SewagePlantId to a list of Ids that are given as:
var sewagePlantIds = UnitOfWork.GetAll<UserGroup>()
.Where(group => group.Id == webAppPrincipal.GroupId)
.SelectMany(group => group.SewagePlantId).Select(sewageplant => sewageplant.Id).ToList();
I have difficulties with the order of joining the 3 tables and where/how to restrict the SewagePlantId to the given list.
Can you try something similar to it please for joining part
from d in Duty
join c in Company on d.CompanyId equals c.id
join s in SewagePlant on c.SewagePlantId equals s.id
select new
{
duty = s.Duty.Duty,
CatId = s.Company.CompanyName,
SewagePlantName=s.SewagePlant.SewagePlantName
// other assignments
};
var obj = from trns in context.tblPartyRegistrations
join st in context.tblSellingTrans
on trns.PartyRegId equals st.Fk_PartyRegId
join pt in context.tblPartyRemainings
on trns.PartyRegId equals pt.fk_PartyId
select new
{
trns.Name,
trns.PhoneNo,
trns.Address,
st.RecivedAmount,
st.Date,
st.CustomerType,
st.MilkRate,
st.Mltr,
st.Mkg,
st.NtAmnt,
st.RemaningAmount,
pt.Remainingammount
};

Can we use if statement in linq for deciding to join or not?

I want to include a table in some conditions in Linq.
I am looking for sth like this:
var query = from x in context.Messages
if(x.senderID != 0)
{
join et in context.ETs on x.senderID equals et.ID
}
where x.Getter == SSN
select new { x.id, x.message}
Is this kind of approach possible or do I have to write two different linq queries and then I will combine them?
var query = from a in context.Messages
join b in context.ETs
on a.senderID equals b.ID
into temp
from b in temp.DefaultIfEmpty()
where a.Getter == SSN
select new { a.id, a.message}

C# LINQ: How to stack LINQ queries correctly

I have a form that allows the user to perform a myriad of searches. The table(s) that need to be joined differ depending on the search criteria entered. (My example below is very simplistic because both tables use the same sub-tables to join on, but the actual problem is not as simple.)
I've been using a technique I call LINQ stacking, like this:
IQueryable<LogENT> results = Context.AssignedLogsENT.Where(l => l.AgencyId);
if(txtFirstName.Text != null)
results = from r in results
join a in Context.LogAssignmentsENT on r.DisplayLogId equals a.LogId
join p in Context.PersonsENT on a.ObjectId equals p.DisplayPersonId
&& !a.Deleted &&
p.FirstName.StartsWith(Object.FirstName)
select r;
if(txtLastName.Text != null)
results = from r in results
join a in Context.LogAssignmentsENT on r.DisplayLogId equals a.LogId
join p in Context.PersonsENT on a.ObjectId equals p.DisplayPersonId
&& !a.Deleted &&
p.LastName.StartsWith(Object.LastName)
select r;
So you see if a certain text field is set, I add to the query as necessary. This actually works fine, except that when I use SQL Profiler to view the generated query, it is INNER JOINing the tables each time I add a new criterion.
i.e. the LogAssignments table is included 3, 4, 5 times. Is there a way I can prevent it from JOINing the same table more than once?
Or, is there a better way I can do this? I've looked at Predicate Builder however it doesn't seem to permit joining tables, which is a requirement in my case.
Thanks!
IQueryable<LogENT> results = Context.AssignedLogsENT.Where(l => l.AgencyId);
results = from r in results
join a in Context.LogAssignmentsENT on r.DisplayLogId equals a.LogId
join p in Context.PersonsENT on a.ObjectId equals p.DisplayPersonId
&& !a.Deleted
select r;
if(txtFirstName.Text != null)
results = from r in results
p.FirstName.StartsWith(Object.LastName)
select r;
if(txtLastName.Text != null)
results = from r in results
p.LastName.StartsWith(Object.LastName)
select r;
If you use just one query, you could modify it something like this:
results = from r in results
join a in Context.LogAssignmentsENT on r.DisplayLogId equals a.LogId
join p in Context.PersonsENT on a.ObjectId equals p.DisplayPersonId
&& !a.Deleted &&
(txtFirstName.Text != null || p.FirstName.StartsWith(Object.FirstName)) &&
(txtLastName.Text != null || p.LastName.StartsWith(Object.LastName))
select r;
You can build your base result and then dynamically add the where clauses.

Categories

Resources