Linq To Sql Join With Dynamically Structured List - c#

I have a Generic Collection List which dynamically selects its columns via the Entity Framework 6.0, using the Dynamic Linq Library.
var AnonymousList = context.Table.Select("new (FIELD_1, FIELD_2)")
My current concern is when joining the dynamically structured list with another list, because
in the join clause, naturally I am unable to reference the columns of the dynamically structured list.
List<CreatedDTO> Holder = from dynamictable in AnonymousList join table2 in context.Table2 on new { dynamictable.FIELD_1 } equals new { table2.FIELD_1 }
I have thought of an alternative which is to first get the data from the table and initialize it in another DTO, then dynamically select the column but that hit a wall too.

you can use dyanmic join by string type like below:
var Holder = AnonymousList.Join(table2,"it.FIELD_1","FIELD_1","new (outer.FIELD_1, outer.FIELD_2)");
e.g : northwind dynamic join order and employee

Related

Linq Query for a particular scenario

Class Demo
{
public int Id{get;set;};
public string Name{get;set;}
public int Parent{get;set;};
public IList<Demo> children{get;set;}
}
Now my code returns List demos. The data is three level nested. I mean List can
contain again Children1 based on each upper level Id matching nested level Parent. It goes another level down where the upper Children1 each ID matches nested Parent and another List of Demos. How can I write an optimized query from it. *
List Demos will have huge data then each Demo Id matches with Parent if matches List of Children (suppose children1) is fetched and then based on the each child in Children 1 which matches Id with Parent another List of Children is filled.
Since you are saying Linq To SQL, I assume this has a backing table with a self join which is already an optimized way of defining such structures. If you generate your Linq To SQL model from such a table then your model would already have navigational properties for 'parent' and 'children'. SQL Server sample database's Employees table is a good example for this. Based on its model you would have something like:
var e = Employees.Select(em => new {
em.EmployeeID,
em.FirstName,
em.LastName,
em.ReportsToChildren
});
and that would generate this SQL:
SELECT [t0].[EmployeeID], [t0].[FirstName], [t0].[LastName], [t1].[EmployeeID] AS [EmployeeID2], [t1].[LastName] AS [LastName2], [t1].[FirstName] AS [FirstName2], [t1].[Title], [t1].[TitleOfCourtesy], [t1].[BirthDate], [t1].[HireDate], [t1].[Address], [t1].[City], [t1].[Region], [t1].[PostalCode], [t1].[Country], [t1].[HomePhone], [t1].[Extension], [t1].[Photo], [t1].[Notes], [t1].[ReportsTo], [t1].[PhotoPath], (
SELECT COUNT(*)
FROM [Employees] AS [t2]
WHERE [t2].[ReportsTo] = [t0].[EmployeeID]
) AS [value]
FROM [Employees] AS [t0]
LEFT OUTER JOIN [Employees] AS [t1] ON [t1].[ReportsTo] = [t0].[EmployeeID]
ORDER BY [t0].[EmployeeID], [t1].[EmployeeID]
Using ToList() on this is a slight detail for enumeration.
Note: Using a utility like LinqPad, you can test this quickly and easily.

Is that possible to return a whole join table data to datagridview instead of specifying the item one by one?

I am trying to get all data from the join table to data review, but what I learn is just to specify the attributes one by one in the SELECT statement as following code:
var query = (from inv in db.tblinventories
join sup in db.tblsuppliers on inv.SupplierID equals sup.SupID into left
from sup in left.DefaultIfEmpty()
select new { inv.Invnum,inv.Model, sup.name }).ToList();
this.dgvPOS.DataSource = query;```
Is this the only way to fetch all data? Because in ORACLE SQL the way is quite simple by using "*" to represent all attributes like this:
SELECT *
FROM tblinventories
LEFT JOIN tblsuppliers
ON tblinventories.SupplierID = tblsuppliers.SupID;

Entity Framework Core store joined table in a variable [duplicate]

This question already has answers here:
Join two tables using linq, and fill a Dictionary of them
(3 answers)
Closed 5 years ago.
I'm joining two tables with Entity Framework like so :
List<Drivers> drivers;
drivers = (from dr in context.Drivers
join per in context.Person on dr.dr_no_person equals per.per_id
select new { dr, per }).ToList();
Of course it doesn't work since {dr, per} is an anonymous type and cannot be translated to Drivers.
My question: is there any way to store what my query returns in a variable, so that I could return it as a list to eventually show it in a DataTable?
You can either declare drivers to be a list of anonymous type:
var drivers = (...).ToList();
Or you can create a Drivers object in the query:
drivers = (from dr in context.Drivers
join per in context.Person on dr.dr_no_person equals per.per_id
select new Drivers { ... }).ToList();
If you want to assign the result to a simple DataGridView and have columns displayed, you will have to pull out the values you want.
var drivers = (from dr in context.Drivers
join per in context.Person on dr.dr_no_person equals per.per_id
select new { dr.dr_no_person, per.per_id, per.name, ... }).ToList();
Unfortunately LINQ doesn't have an easy equivalent to * from SQL. I have a (quite complicated) extension method that allows combining two anonymous types, but it isn't for the faint-hearted, and it isn't strongly typed - it returns the new anonymous type as object.

Linq Multiple Joins

I have some sql tables that I need to query information from my current query that returns a single column list is:
from f in FactSales
where f.DateKey == 20130921
where f.CompanyID <= 1
join item in DimMenuItems
on f.MenuItemKey equals item.MenuItemKey
join dmi in DimMenuItemDepts
on item.MenuItemDeptKey equals dmi.MenuItemDeptKey
group f by dmi.MenuItemDeptKey into c
select new {
Amount = c.Sum(l=>l.Amount)
}
This returns the data I want and it groups correctly by the third table I join but I cannot get the Description column from the dmi table. I have tried to add the field
Description = dmi.Description
but it doesnt work. How can I get data from the third table into the new select that I am creating with this statement? Many thanks for any help.
Firstly you are using Entity Framework COMPLETELY WRONG. Linq is NOT SQL.
You shouldn't be using join. Instead you should be using Associations.
So instead, your query should look like...
from sale in FactSales
where sale.DateKey == 20130921
where sale.CompanyID <= 1
group sale by sale.Item.Department into c
select new
{
Amount = c.Sum(l => l.Amount)
Department = c.Key
}
By following Associations, you will automatically be implicitly joining.
You should not be grouping by the id of the "table" but by the actual "row", or in Object parlance (which is what you should be using in EF, since the raison d'etre of an ORM is to convert DB to Object), is that you should be grouping by the "entity" rather than they the "entity's key".
EF already knows that the key is unique to the entity.
The grouping key word only allows you to access sale and sale.Item.Department after it. It is a transform, rather than an operator like in SQL.

C# Linq to Entity Framework multiple unrelated queries

I have a situation where I need data from multiple database tables.
Table 1 - has list of columns which needs to be displayed on front end html, angular kendo grid - which is configurable from separate Admin configuration.
Table 2 (joining of some other tables)- has the data which needs to be displayed on the angular front end.
My linq here which I am using currently is as below.
Query 1: to get list of columns to be displayed on Grid
var columns = from cols in _context.columns
select cols.colNames;
Query 2: Get the actual data for list
var data = from cust in _context.customer
join details in _context.custDetails on cust.id equals details.custid
join o in _context.orders on cust.id equals o.custid
where cust.id == XXXX
select new Customer
{
Id = cust.Id,
Name = cust.Name,
Address = details.Address,
City = details.City,
State = details.State,
OrderDate = o.OrderDate,
Amount = o.Amount
//15 other properties similarly
};
returns IQueryable type to Kendo DataSourceRequest
Currently, From my ui I have been make two api calls one for columns and one for getting the actual data, and show/hide the columns which are configured in the columns table.
But the problem is if anyone looks at the api calls on the network or on browser tools they could see the data being returned for the columns that are to be hidden which is a security problem.
I am looking for a single query for my api which returns the data using second query which should be smart enough to send the data only for configured columns (there could be 30 different columns) and set the other properties to null or doesn't select them at all. there are some properties which needs to be returned always as they are being used for some other purpose.
I searched many resources on how could I generate dynamic linq select using the configured columns.
Please some one help me in resolving this problem
you can do something like this. Assuming you columns tables a Boolean column Display and when it is true Column will be displayed and when it is false it wont be displayed.
var columns = (from cols in _context.columns
select cols).ToList(); // note I am getting everything not just column names here...
var data = from cust in _context.customer
join details in _context.custDetails on cust.id equals details.custid
join o in _context.orders on cust.id equals o.custid
where cust.id == XXXX
select new Customer
{
Id = cust.Id,
Name = cust.Name,
Address = details.Address,
City = details.City,
State = details.State,
OrderDate = o.OrderDate,
Amount = o.Amount
//15 other properties similarly
}.ToList();
var fileterdData = from d in data
select new Customer
{
Id = DisplayColumn("ID",columns)? cust.Id:null,
Name = DisplayColumn("Name",columns)? cust.Name:null,
Address = DisplayColumn("Address",columns)? details.Address:null,
// do similarly for all other columns
}.AsQueryable(); // returns IQueryable<Customer>
private bool DisplayColumnn(string columnName,List<Columns> cols)
{
return cols.Where(x=>x.ColumnName==columnName).First().Display();
}
So now you will have this code as part of one web API call which is going to do two SQL calls one to get columns and other to get data then you will use Linq To Entity filter columns which you dont want ( or want them to null). return this filtered data back to UI.

Categories

Resources