Can I combine these two Linq queries - join

I am trying to combine SharePoint data with a legacy database data and I can get the data, but I need to do it in two queries. Here are the two Linq queries:
var query =
(from dtEai in result.AsEnumerable()
join allAP in dtAllAirports.AsEnumerable()
on dtEai.Field<int>("AirportID") equals allAP.Field<int>("ID")
select new
{
Region = allAP.Field<string>("region")
}
);
and the second which gets me my result:
var join =
(
from table in query
group table by table["Region"] into groupedTable
select new
{
Key = groupedTable.Key,
Count = groupedTable.Count()
}
);
not being an expert in Linq I converted the SharePoint lists into datatables so I could do the join. Can I combine this into a single query?

I had to make two linq methods due to the fact that I did not want to try to method chain and do a groupby afterwards. It just would of been too confusing.

Related

trying to convert sql to linq sql

I'm trying to convert this SQL code to linq sql. But I don't understand even with the doc... someone can help me please ?
select prcleunique, LibelleProjet, from projet a
where eqcleunique in (select EqCleunique from Compo where uscleunique = '{0}')
and (a.socleunique in (select socleunique from utilisat where uscleunique = '{0}') or a.socleunique is null)
and a.archive = 2 order by LibelleProjet", idUtilisateur);
Those nested sql queries can be broken down nicely in Linq. Every time you have a select have a seperate linq query:
var clause1 = from row in _db.Compo where uscleunique == '{0}' select EqCleunique;
Then use the clauses in the last query
var result = from row in _db.project where clause1.Contains(row.eqcleunique) select row.whatever;
I hope this example is enough to get you started.

How to deal with Null Values in OUTER JOINS using Entity Framework 6

I need to process the query at the bottom of this post in C#. The query works, but I don't know how to use it in EF6. I used a method and a viewmodel for it (variable query = the query below). But when it encounters null values in the OUTER JOIN, int32 cant accept this value when calling .toList(). What's the best way to deal with it?
var result = context.Database.SqlQuery<TourQueryViewModel>(query);
var reslist = result.ToList();
I tried my first steps with LINQ, but I dont get it how to translate into LINQ itself or the query-methods, that are equivalent to it. So I am hoping for your help.
SELECT toursdata.TourId AS TourId, toursdata.Tourname AS Tourname,toursdata.Tourdate Tourdate,
toursdata.VehicleId AS VehicleId, toursdata.VehicleName AS VehicleName, toursdata.LicenseNumber AS LicenseNumber,
Employees.EmployeeId AS EmployeeId, Employees.Gender AS Gender, Employees.Forename AS Forename, Employees.Surname AS Surname
FROM (
SELECT te.TourId, te.Tourname, te.Tourdate,
Vehicles.VehicleId, Vehicles.VehicleName, Vehicles.LicenseNumber,
TourEmployees.EmployeeId
FROM TourEmployees RIGHT OUTER JOIN Tours AS te ON TourEmployees.TourId = te.TourId,
Tours AS tv INNER JOIN Vehicles ON tv.VehicleId = Vehicles.VehicleId
WHERE tv.TourId = te.TourId
) toursdata
LEFT OUTER JOIN Employees ON toursdata.EmployeeId = Employees.EmployeeId
To eliminate the null problem, I changed the data type of the corresponding entity-attribute to a nullable-type
int turned to int?.
Didnt know about that language feature.

Alternative to using String.Join in Linq query

I am trying to use the Entity Framework in my ASP MVC 3 site to bind a Linq query to a GridView datasource. However since I need to pull information from a secondary table for two of the fields I am getting the error
LINQ to Entities does not recognize the method 'System.String Join(System.String, System.Collections.Generic.IEnumerable'1[System.String])' method, and this method cannot be translated into a store expression.
I would like to be able to do this without creating a dedicated view model. Is there an alternative to using String.Join inside a Linq query?
var grid = new System.Web.UI.WebControls.GridView();
//join a in db.BankListAgentId on b.ID equals a.BankID
var banks = from b in db.BankListMaster
where b.Status.Equals("A")
select new
{
BankName = b.BankName,
EPURL = b.EPURL.Trim(),
AssociatedTPMBD = b.AssociatedTPMBD,
FixedStats = String.Join("|", from a in db.BankListAgentId
where a.BankID == b.ID &&
a.FixedOrVariable.Equals("F")
select a.AgentId.ToString()),
VariableStats = String.Join("|", from a in db.BankListAgentId
where a.BankID == b.ID &&
a.FixedOrVariable.Equals("V")
select a.AgentId.ToString()),
SpecialNotes = b.SpecialNotes,
};
grid.DataSource = banks.ToList();
grid.DataBind();
If you're not overly worried about performance (since it has subqueries, it may generate n+1 queries to the database, and if the database rows are large, you may fetch un-necessary data), the simplest fix is to add an AsEnumerable() to do the String.Join on the web/application side;
var banks = (from b in db.BankListMaster
where b.Status.Equals("A") select b)
.AsEnumerable()
.Select(x => new {...})
At the point of the call to AsEnumerable(), the rest of the Linq query will be done on the application side instead of the database side, so you're free to use any operators you need to get the job done. Of course, before that you'll want to filter the result as much as possible.

Join Non ContentPart Table to ContentPart Table Using Orchard HQL API

I am trying to perform a simple join between two different tables using the Orchard HQL API. The problem is that one of the tables is not a ContentPartTable. Is this possible??
Here is what it would look like in regular SQL:
Select * From ItemPartRecord
Join ItemRecord
On ItemRecord.ItemId = ItemPartRecord.ItemId
Where ItemRecord.Price Between 1000 and 10000
How exactly could I go about doing this?
If anyone is wondering how to do this:
//Join the non content part table
var defaultHqlQuery = query as DefaultHqlQuery;
var fiJoins = typeof(DefaultHqlQuery).GetField("_joins", BindingFlags.Instance | BindingFlags.NonPublic);
var joins = fiJoins.GetValue(defaultHqlQuery) as List<Tuple<IAlias, Join>>;
joins.Add(new Tuple<IAlias, Join>(new Alias("ExampleNamespace.Data.Models"), new Join("ExampleRecord", "ExampleAlias", ",")));
Action<IHqlExpressionFactory> joinOn = predicate => predicate.EqProperty("valueToJoinOn", "aliasToJoinOn.valueToJoinOn");
query = query.Where(
alias => alias.Named("ExampleAlias"),
joinOn
);

How can I set a many-to-many EntityCollection in Entity Framework efficiently?

When Entity Framework generates an ObjectContext for a two database tables (let's say Table1 and Table2) connected with a many-to-many relationship table, it doesn't create an object for the xref table, opting instead for collection properties on either end of the relationship. So on Table1 you have EntityCollection<Table2> Table2s and on Table2 you have EntityCollection<Table2> Table1s. In most cases that's actually pretty great...
However, in this scenario, I have a list of integers that represent the database IDs of the Table2 rows that should be in the Table1.Table2s collection.
I can't see any way to just set that collection using the entity keys, so I'm stuck selecting these into the ObjectContext, which is already a ton of work to do for no reason. I let myself hope that LINQ-to-Entities will intelligently defer the execution and perform it all on the SQL server like I would like (though my Where uses Contains, which may or may not be correctly translated to IN() in SQL). So I can go as far as:
table1instance.Table2s.Clear();
var table2sToInclude = context.Table2s.Where(
t =>
listOfTable2DatabaseIds.Contains(t.Id));
But there's no EntityCollection<T>.AddRange(IEnumerable<T>) or anything, nor is there an IEnumerable<T>.ToEntityCollection<T>() extension method of course, so I don't know what to do with these results at this point. All I can do is
foreach (var table2 in table2sToInclude)
{
table1instance.Table2s.Add(table2);
}
which seems ridiculous and I know will force a lot of unnecessary evaluation.
Is there a "correct", or, perhaps, "less lame" way to do this?
No EF will not defer any query execution. There is nothing like insert from select. Linq-to-entities is just query language and responsibility of query is to execute. It is strictly separated from persistence functionality offered by EF itself.
If you want to create relations between existing item from table1 and exiting items from table2 you can use code like this:
using (var ctx = new YourContext())
{
var table1 = new Table1 { Id = 123 };
ctx.Table1s.Attach(table1);
foreach (var table2 in table2sToInclude.Select(id => new Table2 { Id = id }))
{
ctx.Table2s.Attach(table2);
order.Table2s.Add(table2);
}
ctx.SaveChanges();
}
This code creates relation between Table1's item with id 123 and all Table2's items from table2sToInclude without loading any single record from the database.
What makes adding records one by one "lame"? Do you understand what is benefit of AddRange? AddRange in typical collection extends capacity of internal array and just copy items to extended array. EntityCollection is not typical array and it must process each added entity. So even if there will be some AddRange it will internally iterate items and process them on by one.

Resources