I have three tables (Table A, B and C).
I would like to do the following:
Left Join A with B and Left join A with C.
Now I have used CreateCriteria, to do the joins using jointype which worked upto a certain point but it's throwing Query exception. It seems this is because it's seems to attempt to left join B with C rather than A and C.
Code:
currencies = session.CreateCriteria(typeof(Currency), "TableA")
.CreateCriteria("FXRates", "TableB",
JoinType.LeftOuterJoin,
Expression.Eq("fxrate.RateDate",date))
.CreateCriteria("FundingRates", "TableC",
JoinType.LeftOuterJoin,
Expression.Eq("fundingrate.RateDate", date))
.Add(Restrictions.IsNotNull("currency.code"))
.List<Currency>();
Apologies in advanced if I have missed out anything or not provided enough detail, let me know if you need more...
You can use NHibernate "QueryOver" to do it:
session.QueryOver<Item_A>()
.Left.JoinQueryOver(item_A => item_A.Item_B)
.Left.JoinQueryOver(item_A => item_A.Item_C)
.TransformUsing(Transformers.DistinctRootEntity)
.List();
Related
I have been having a problem with the following query I constructed it keeps returning null, I am hoping that someone could just point me in the right direction.
The query is meant to return a list of branches that offer a particular service based on a service ID that is given. I have a many-to-many relationship between two tables being branches and services.
from b in database.branches
join bs in database.branch_services on b.branch_id equals bs.branch_id
where bs.service_id == objID
select b;
Here is the valid query, adjust table names to match yours:
database.Services.Where(s => s.ServiceId == 3).First().Branches.ToList();
Have you tried the lambda syntax?
I've periodically seen it written that joins are unnecessary in LINQ to SQL. Most recently, I saw this statement in one of Joseph Albahari's LINQPad samples (Chapter 9 - LINQ Operators > Filtering > Joining > Simple Join).
The comment says:
// Note: before delving into this section, make sure you've read the preceding two
// sections: Select and SelectMany. The Join operators are actually unnecessary
// in LINQ to SQL, and the equivalent of SQL inner and outer joins is most easily
// achieved in LINQ to SQL using Select/SelectMany and subqueries!
I've gone through the Select and SelectMany sections in LINQPad and I definitely want to be doing this the easy way, but my attempts to completely remove joins (and get the same results) have failed.
Anyway, below is the 100% working query I'm trying this out on (full schema pictured below).
(from workOrder in dbContext.WorkOrders.Where(wo => wo.WoId == workOrderLine.WoId)
join projectsBillingSchedule in dbContext.ProjectsBillingSchedules
on workOrder.ProjectId equals projectsBillingSchedule.ProjectId
join partyPricing in dbContext.PARTY_PRICING.Where(pp => pp.END_DATE_ACTIVE == endDateActive)
on projectsBillingSchedule.BillingSchId equals partyPricing.BILLING_SCH_ID
join measuresPartyRetrofitCode in dbContext.MeasuresPartyRetrofitCodes
on partyPricing.PARTY_RETROFIT_CODE_ID equals measuresPartyRetrofitCode.PartyRetrofitCodeId
join measure in dbContext.Measures on measuresPartyRetrofitCode.ConvId equals measure.ConvId
select measure).FirstOrDefault(m => m.ConvId == workOrderLine.ConvId)
Please note, certain entities are omitted from the code because they are not strictly necessary for the query to run properly. Aside from that, you can see the joins are done in order of the relationships in the schema image, i.e., from WORK_ORDERS to MEASURES (start by moving away from WORK_ORDER_LINES):
I have tried some using navigation properties, but I run into 2 problems:
The SQL outputs in multiple statements (N+1 problem?), and
I can't seem to get it all in one statement.
So, back to my question - using the example above (or something else with a lot of joins), how are join operators unnecessary in LINQ to SQL?
UPDATE
Ok, I think I've figured out one solution, but this actually requires more lines of code to achieve the same result.
Since that is the case, I'm not sure why it is worth exclaiming that join operators are unnecessary. I'll leave this question open for a while to see if someone wants to make a compelling case against joins.
(from workOrder in dbContext.WorkOrders.Where(wo => wo.WoId == workOrderLine.WoId)
from projectsBillingSchedule in dbContext.ProjectsBillingSchedules
where workOrder.ProjectId == projectsBillingSchedule.ProjectId
from partyPricing in dbContext.PARTY_PRICING.Where(pp => pp.END_DATE_ACTIVE == endDateActive)
where projectsBillingSchedule.BillingSchId == partyPricing.BILLING_SCH_ID
from measuresPartyRetrofitCode in dbContext.MeasuresPartyRetrofitCodes
where partyPricing.PARTY_RETROFIT_CODE_ID == measuresPartyRetrofitCode.PartyRetrofitCodeId
from measure in dbContext.Measures
where measure.ConvId == measuresPartyRetrofitCode.ConvId
select measure).FirstOrDefault(m => m.ConvId == workOrderLine.ConvId)
I am using the entity framework database first to build a model of my database. Up to this point I have worked on single tables/entities and it has gone quite smooth to get the data with a query and saving it in a list in order to present the data.
Now I am in a situation where I need to join several tables and find myself in a bit of a struggle. I thougth I could simply join the entities I need since they have a foreign key to eachother, but I am having trouble finding a query that returns the set I want, which is basicly all columns from all tables.
In t-sql I would simply do a LEFT JOIN on the different tables on the keys. I have considered creating a view and then build the model on this view, but I have to be able to update the data as well and a view from the database is not so straight forward to update with the EF as far as I have understood.
I was hoping to do something like the query below, but since I need to update the different tables as well I was wondering if anyone has an elegant solution for how to do this. Or is it something I simply have not understood about joining in EF?
using(var _ctx = new EFEntities())
{
var queryResult = from a in _ctx.a
join b in _ctx.b
on a.b_ID equals b.ID
join c in _ctx.c
on b.c_IDequals c.ID
select new
{
//columns I want
};
}
As has already been mentioned in the comments there should be navigation properties between your classes but if you really want to flatten the data but maintain objects that can be updated elsewhere then you could do something like this:
using(var _ctx = new EFEntities())
{
var queryResult = from a in _ctx.a
join b in _ctx.b
on a.b_ID equals b.ID
join c in _ctx.c
on b.c_IDequals c.ID
select new
{
a = a,
b = b,
c = c
};
}
I simply can not get this to work out at all, so any expert help would be very much appreciated.
I'm trying (as the subject suggests) to join 2 datatables on Zip Code, but return a table which grouped this by State and has a SUM() of sales.
Here's the latest version of my troubles:
var results =(
from a in dtList.AsEnumerable()
join b in dtListCoded.AsEnumerable()
on a.Field<string>("ZIP") equals b.Field<string>("zip")
group a by {a.Field<string>("StateCode")} into g
select new {
StateCode = a.Field<string>("StateCode"),
SumSales = b.Sum(b => b.Field<double>("SUMSales"))
});
I can join the 2 tables but its getting the result i need that seems to be the tricky bit. If need be I will just have to do 2 queries, but that just seems a bit backward.
Thanks in advance.
Two queries wouldn't be any slower (they should be brought together into a single SQL query upon execution), and would be a lot more readable, transparent during debugging and reusable. I'd recommend breaking it down.
I can't seem to find any solid answer to the problem, I'm hoping someone will be able to help me here.
Sample query:
select * from A a inner join B b on a.Id = b.Id Or a.Date = b.Date
Basically I want to know if it's possible to implement the second part of the join condition using criteria, and if it is possible, how to go about it. If anyone can please let me know, that will be great! Thanks a bunch!
It might be, but that query is more clear written in HQL:
select a from A a, B b where a.Id = b.Id or a.Date = b.Date
As you can see, it's almost the same as the SQL.
Unfortunately you cannot define ANSI syntax joins with NHibernate.
With NH2 and onward you can define them on HQL using a WITH clause and i say so because if you use Diego's solution you will have to set up a ISNULL OR pattern in your queries if you want to perform multiple joins.
to add conditions, use Expressions. For the OR disjunction, its less complex if you use Expresion.In
session.CreateCriteria(typeof(A), "a").CreateCriteria("B", "b", NHibernate.SqlCommand.JoinType.FullJoin)
.Add(Expression.Eq("a.Date", a.Date))
.Add(Expression.Eq("b.Date", b.Date))