Select all columns after JOIN in LINQ - c#

I have two tables, Table1 and Table2. I want to perform, say, a left outer join:
var myOutput = from object1 in Table1
join object2 in Table2
on object1.Property1 equals object2.Property2 into Table3
from output in Table3.DefaultIfEmpty()
select new
{
object1.Property1,
object1.Property2,
//...
output.Property3,
output.Property4,
//...
};
As you can notice, I want to select all the properties of both objects from the resulting table (the enumerables considered while joining contain the objects of certain types - these are different for both relations). Of course, I can select the properties in the anonymous select, as shown in the example.
My question is how to avoid specifying all the properties manually? I would like to have something like SELECT * FROM TABLE3, where TABLE3 is a resulting relation (after joining TABLE1 and TABLE2).
Thanks in advance for the clues.

You have to specify each manually if you want to project into a flattened type. Your other option is to just have your combined type contain both objects, and the objects will naturally bring along their properties.
select new
{
Object1 = object1,
Object2 = output
};
And you would work with it like myObj.Object1.Property1, myObj.Object2.Property4, etc.
One final option that still involves some manual work is to define an appropriate type and have a constructor or a builder method that does the work of segmenting out your object properties into a flattened type. You still perform the manual mapping, but you isolate it from your query logic.
select new CombinedType(object1, output);
//or
select builder.GetCombinedType(object1, output);

Related

LINQ to DataTable Join Query using OR condition

I have two DataTables with different data,common columns in both are quantity and Itemcode. I want to join the two tables together where two fields, (DataTable1.itemcode=DataTable2.itemcode) AND (DataTable1.quantity=DataTable2.quantity) OR ((DataTable1.quantity+1)=DataTable2.quantity) OR ((DataTable1.quantity+2)=DataTable2.quantity) . How would I write this in LINQ?
if item code is same and quantity is equal,exceeds by 1 or 2 then I should get joined result.
I tried using anonymous objects but that is for AND condition and OR condition was not fulfilled,so only itemcode and any one of these conditions was achieved at a time?
Please suggest me the correct way to do it?
You have to use the following syntax to access fields of the dataset:
[DataTable Name].Field<string>(indexNo or ColumnName)
So you can write the following linq to put a join between two data tables:
from t1 in dataTable.AsEnumerable()
//join between two tables
join t2 in dataTable2.AsEnumerable() on t1.Field<string>(0) equals t2.Field<string>(0)
//where conditions
where t1.Field<string>(0) == [value]
//select clause
select t1.Field<string>(colmNo)
Also you can convert the two data tables to IEnumerable by creating extension method.

Using the SQL "IsNull()" command in NHibernate criteria in C#

I need to be able to use with NHibernate criteria, the SQL's IsNull() function in C#.NET. I don't need to use it with LINQ.
Meaning that Table1 has the following columns:
Name | Description
Table2 has the following columns:
OriginalDescription | TranslatedDescription
And Table1.Description = Table2.OriginalDescription.
How would I write the following SQL statement with NHibernate criteria:
SELECT Table1.Model, IsNull(Table2.TranslatedDescription, Table1.Description)
FROM Table1
LEFT JOIN Table2 ON Table2.OriginalDescription = Table1.Description
The SQL statement above will give me the Names, and TranslatedDescriptions if the TranslatedDescriptions exist, otherwise it will return the Descriptions, for the records.
There cannot be duplicates of OriginalDescription in the Table2.
The solution of the ISNULL could be expressed like this:
// here is the criteria of the "Entity1" and the join to the "Entity2"
var criteria = session.CreateCriteria("Entity1", "table1");
criteria.CreateAlias("Entity2", "table2");
// here we drive the SELECT clause
criteria.SetProjection(
Projections.ProjectionList()
.Add(Projections.Property("Model"))
.Add(Projections.SqlFunction("COALESCE", NHibernateUtil.String
, Projections.Property("table2.TranslatedDescription")
, Projections.Property("table1.Description")
))
);
// just a list of object arrays
var list = criteria.List<object[]>();
So, what we do here, is a call of the SqlFunction. In this case one of the out-of-the-box mapped in many Dialects coming with NHibernate (but we can even extend the dialect with custom ones, an example how to: Nhibernate count distinct (based on multiple columns))
Must note, that the JOIN Clause is coming from the mapping. So this Table2.OriginalDescription = Table1.Description must come from a mapped relation many-to-one

Linq query to join 4 tables

I have a table called deliveries with columns id,shiftid, occurrence,delfee). I have three other tables delcash,delcc,delsplit. Del cash has columns (id,cost,paid), delcc has columns (id,cccost,ccpaid,cashtip), delsplit has columns(id,cashcost,cashpaid,cccost,ccpaid). The id links the delivery entries to one of the three other tables based on the type of payment. I am trying to get a list where the tables are joined together in a way so i can iterate through a list and get a table in a view that shows each delivery in order of occurrence as well as the tip and delivery fee of each delivery. Any idea if it is possible to do this? Or should I just use SQL?
SELECT deliveries.occurrence, deliveries.delfee,delcash.cost,delcash.paid,delcc.cost,delcc.paid,delcc.cashtip,
delsplit.cashcost,delsplit.cashpaid,delsplit.cccost,delsplit.ccpaid
FROM deliveries
LEFT JOIN delcash
ON deliveries.id = delcash.id
LEFT JOIN delcc
ON deliveries.id = delcc.id
LEFT JOIN delsplit
ON deliveries.id = delsplit.id
You can make a new class and let the three cost tables inherit from this class then you can apply the Table per Concrete Type strategy for mapping the tables.
see:
http://weblogs.asp.net/manavi/archive/2010/12/24/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-1-table-per-hierarchy-tph.aspx
OR redesign your database and apply Table per type strategy.
Try something like this:
var joinedDel = from delivery in tblDeliveries
join delC in tblDelCash on delivery.id equals delC.id
join delCC in tblDelCreditCard on delivery.id equals delCC.id
join delSplit in tblDelSplit on delivery.id equals delSplit.id
select new {
//Then create a new instance of Anonymous object where you will set all values of its properties
//For example, you can set ShiftID = delivery.ShiftID
};
I will also suggest to normalize first your tables(see this link for your reference) . This will give you more understanding on how will you join those tables properly.

Querying a join table using LINQ

Okay this could very likely be a silly question. I am using Entity Framework Code First. I have two classes, User and Event, that have a Many-To-Many relationship. When EF generates my database tables, it creates a join table, which I call Users_Events. This table has two columns, User_ID and Event_ID. Everything is fine so far.
I want to pull an Event from my database and serialize it to JSON. This also works perfectly except I cannot pull an Event's Users because this would create a circular reference. What I want to do here is query my join table and get all the User_IDs that have an associated Event_ID equal to the ID of the Event I am serializing.
How can I do this?
I don't know exactly what you want to end up with in your JSON, but I suspect you want to select into a new anonymous type and serialize that instead. Something along these lines maybe:
from e in myContext.Events
where e.ID = 123
select new {
Event = e,
UserIDs = (from u in e.Users select u.ID)
}

Automatic join with NHibernate / Many-to-one / HQL

I'm working on a .NET C# project on which I had to use NHibernate Mapping Attributes to map my objects to my tables in my database.
Now let's explain what my problem is.
I have two mapped classes, for example ClassA and ClassB. In my database, table A contains a foreign key referencing the primary key of table B. Hence, I have added to ClassA an instance of ClassB mapped in many-to-one:
private ClassB b;
[ManyToOne(0, Name = "B", Column = "ID_TABLE_B_TABLE_A", Class = "ClassB", Update = false, Insert = false)]
public virtual ClassB B
{
get { return b; }
set { b= value; }
}
Now, I want to check the value of a field of ClassB when I'm accessing ClassA. I write the query in HQL:
Session.CreateQuery("select a.Id from ClassA a where a.ClassB.Name = 'xxx' ");
Here's the generated SQL:
select tablea0_.ID_TABLE_A as col_0_0_
from TABLE_A tablea0_, TABLE_B tableb1_
where tablea0_.ID_TABLE_B_TABLE_A = tableb1_.ID_TABLE_B
and tableb1_.NAME_TABLE_B='xxx'
I thought this kind of HQL query was supposed to generated a join statement rather than a where statement, as I have defined a many-to-one association between the two classes. Something like this would've been better:
select tablea0_.ID_TABLE_A as col_0_0_
from TABLE_A tablea0_
left join TABLE_B tableb1_ on tableb1_.ID_TABLE_B = tablea0_.ID_TABLE_B_TABLE_A
where tableb1_.NAME_TABLE_B='xxx'
In my opinion, join looks cleaner to where. I would like to know if there is a way to set up the behaviour of NHibernate accordingly, without specifying the join statement explicitly in the HQL query.
Any help would be appreciated !
The join works like this:
Session.CreateQuery("select a.Id from ClassA a join a.ClassB b where b.Name = 'xxx' ");
Session.CreateQuery("select a.Id from ClassA a left join a.ClassB b where b.Name = 'xxx' ");
Session.CreateQuery("select a.Id from ClassA a left outer join a.ClassB b where b.Name = 'xxx' ");
Of course, it's now for you to figure out which join works best for you. :)
More information # http://docs.jboss.org/hibernate/stable/core/reference/en/html/queryhql.html#queryhql-joins
On a side note, if you want to be one of the cool kids, you could always use Linq to NHibernate:
var result = Session.Linq<ClassA>().Where(a => a.B.Name == 'xxx').ToList();
Would generate an inner join query.
It's been a while since I worked with NHibernate, but I don't think you can force it to do this.
You can try specifying "fetch=join" in the many-to-one mapping, but if memory serves, this only changes the strategy NHibernate uses when fetching related entities in general, not how it translates a custom HQL query to SQL.
But why even worry about it?
In 99% of the cases I actually looked at the generated SQL, it was because incorrect SQL was generated (usually because I made a mistake), or to investigate performance issues.
The generated SQL depends on the datababase dialect. Oracle did not support the ANSI join syntax until 9i so it's possible that the Oracle dialect in NHibernate still uses the old syntax for inner joins. What SQL is produced by a left join? If it's tablea0_.ID_TABLE_B_TABLE_A += tableb1_.ID_TABLE_B then it's using the old syntax for those as well.

Categories

Resources