select data from multiple tales using linq query - linq

I have 2 tables I want to select all records from table one but in second table i want select all records that's on the id base that id is not related to table one .i want to do this in linq query .
any help

For what I could understand, you want to do a join between the two tables:
var query = database.FirstTable // starting point - the first table from your question
.Join(database.SecondTable, // the second table
first => first.ID, // Select the primary key (the first part of the "on" clause in an sql "join" statement)
second => second.first_ID, // Select the foreign key (the second part of the "on" clause)
(first, second) => new { First = first, Second = second }) // selection
.Where(result => result.first.ID == id); // where statement

Related

Laravel query builder select all except specific column

I have 2 tables with the same columns except the second table have one more column, this column is foreign key of the first;
what i want is to make union query;but for union the column must the same; so i want to select all column except for the column distinct;
The easy way is to provide in select all the same column:
$a = Table1::select(['column1', 'column2', 'etc...']);
$b = Table2::select(['column1', 'column2', 'etc...']);
and go with $a->union($b)->get();
but if i have too much column, i end up with so much column to provide in the select function; so what i want is to provide in the query the column that i don't want to retrieve;
i can put protected $hidden in the second table model but for some reason i need this distinct column on some other query;
Get all columns name by Schema::getColumnListing($table);
And computes the intersection of arrays
array_intersect($columnsName1, $columnsName2);
I haven't done it with 2 tables but I am using collections and rejecting certain columns on a similar project:-
$row = Table1::firstOrFail();
$exclude=['column_1', 'column_2'];
return collect(array_keys($row->getAttributes()))
->reject(function ($name) use ($row, $exclude) {
return in_array($name, $row->getHidden())
|| in_array($name, $exclude);
}
);

LINQ Left Outer Join only the first record

I'm working on a LINQ query that joins three tables. For the Orders and OrderInfo table I expect a single record in each table for a given order id. However for the ShipRate table, there could be 0, 1 or more records for a given order id. So for this table I am using a left outer join. The query shown below is working if 0 or 1 records exist in the ShipRate table, but for instances where the number of records is > 1, I need to select only the most recent ShipRate record. I tried to do this by replacing the line:
from shipRate in sr.DefaultIfEmpty()
with this:
from shipRate in sr.OrderByDescending(r => r.CreateDate).Take(1).DefaultIfEmpty()
but the query takes forever, as if it is loading the entire ShipRate table. Where have I gone wrong?
var query = (from order in db.Orders
join info in db.OrderInfo
on order.OrderId equals info.OrderId
join shipRate in db.ShipRate
on info.OrderId equals shipRate.OrderId
into sr
from shipRate in sr.DefaultIfEmpty()
where order.OrderId == orderId
select new
{
OrderId = order.OrderId,
OrderDetail = info.OrderDetail,
Carrier = shipRate.Carrier
}).SingleOrDefault();
With a proper model definition your query would be like:
var query = (from order in db.Orders
where order.OrderId == orderId
select new
{
OrderId = order.OrderId,
OrderDetail = order.OrderInfo.OrderDetail,
Carrier = order.OrderInfo.ShipRates.OrderBy(sr =>sr.CreateDate).FirstOrDefault()
}).SingleOrDefault();
I can't be sure though, because you didn't supply sample data and model.
Cetin Basoz's answer is a good one: ideally you'd set up your model in a way that allows you to use navigation properties. If you're using a model generated from your database schema, that typically means setting up foreign and primary keys properly.
If you can't do that, you should still be able to get a similar effect by writing SQL like this:
var query = (from order in db.Orders
where order.OrderId == orderId
let orderInfo = db.OrderInfo.FirstOrDefault(info => order.OrderId == info.OrderId)
let currentShipRate = db.ShipRate
.Where(shipRate => info.OrderId == shipRate.OrderId)
.OrderByDescending(shipRate => shipRate.CreateDate)
.FirstOrDefault()
select new
{
OrderId = order.OrderId,
OrderDetail = orderInfo.OrderDetail,
Carrier = currentShipRate.Carrier
}).SingleOrDefault();
However, LINQ to SQL isn't nearly as good at building advanced queries as Entity Framework, and the symptoms you're describing might be an indication that it's actually doing multiple database round-trips instead of a join. I'd recommend logging the query that you're producing (prior to the .SingleOrDefault()) either by calling .ToString() on the query or by executing your query in LINQPad and clicking on the SQL tab. That might give you a clue as to why the query is misbehaving.
There seems to be a one-to-one relation between Orders and OrderInfos: every Order has exactly one OrderInfo, and every OrderInfo is the info of exactly one Order, namely the Order that the foreign key OrderId refers to.
On the other hand, there seems to be a one-to-many relation between Orders and ShipRates. Every Order has zero or more ShipRates, every ShipRate is a ShipRate of exactly one Order, namely the Order that the foreign key OrderId refers to.
You want several properties of "Orders, each Order with its one and only OrderInfo and its zero or more ShipRates"
Whenever you have a one-to-many relation, and you want "items with their zero or more sub-items", like Schools with their Students, Customers with their Orders, or in your case: Orders with their ShipRates, consider to use one of the overloads of Queryable.GroupJoin
In the other direction: if you want an item with its one and only other item that the foreign key refers to, like Student with the School he attends, Order with the Customer who created the Order, or Order with its one and only OrderInfo, use Queryable.Join.
I mostly use the overload of GroupJoin that has a parameter resultSelector, so I can select exactly what properties I want.
int orderId = ...
var ordersWithShipRates = dbContext.Orders.GroupJoin(dbContext.ShipRates,
order => order.Id, // from every Order take the primary key
shipRate => shipRate.OrderId, // from every ShipRate take the foreign key to Order
// parameter resultSelector: from every Order, with its zero or more ShipRates
// make one new
(order, shipRatesOfThisOrder) => new
{
// Select the Order properties that you plan to use:
Id = order.Id,
Date = order.Date,
...
ShipRates = shipRatesOfThisOrder.Select(shipRate => new
{
// Select the ShipRate properties that you plan to use:
Id = shipRate.Id,
Value = shipRate.Value,
...
})
.ToList(),
// A simple join to get the one and only OrderInfo
OrderInfo = dbContext.OrderInfos.Where(orderInfo => orderInfo.Id == order.Id)
.Select(orderInfo => new
{
// Select the orderInfo properties that you plan to use
Name = orderInfo.Name,
...
})
.FirstOrDefault(),
});

How to compare the column names in one table to the values in another in impala

first is the main table and second is the lookup table.
I need to compare the column names of first table to the values in the second table and if a certain column name is found in any row of the second table then fetch some fields out of second table.
Is it possible to do it in impala?
Table 1
source |location |origin
----------+----------+-------
s1 |india |xxx
Table 2
extractedfrom|lct |lkp_value|map_value
-------------+----------+---------+---------
s1 |location |india |india_x
s1 |origin |xxx |yyyyyy
i need to have something like
final view required
source |location |origin |location_ll|origin_lkp
----------+----------+----------+-----------+----------
s1 |india |xxx |india_x |yyyyy
You should edit your post to be more specific about what you are trying to do and how you wish to join the tables.
The following query should work for you given the example you provided.
SELECT t1.source,
t1.location,
t1.origin,
t2_loc.map_value AS location_lkp,
t2_ori.map_value AS origin_lkp
FROM Table1 t1
JOIN Table2 t2_loc ON t1.source = t2_loc.extractedfrom
AND t1.location = t2_loc.lkp_value
JOIN Table2 t2_ori ON t1.source = t2_ori.extractedfrom
AND t1.origin = t2_ori.lkp_value
WHERE t2_loc.lct = 'location'
AND t2_ori.lct = 'origin'
The trick is that you join to Table2 multiple times - one for each column you wish to match upon.

How to join two table from two different edmx using linq query

How to join two table from two different edmx using linq query..
Is there a way to query from 2 different edmx at a time.
Thanks.
Update
As per your comment, EF wasn't able to parse a combined Expression tree across 2 different contexts.
If the total number of records in the tables is relatively small, or if you can reduce the number of records in the join to a small number of rows (say < 100 each), then you can materialize the data (e.g. .ToList() / .ToArray() / .AsEnumerable()) from both tables and use the Linq join as per below.
e.g. where yesterday is a DateTime selecting just a small set of data from both databases required for the join:
var reducedDataFromTable1 = context1.Table1
.Where(data => data.DateChanged > yesterday)
.ToList();
var reducedDataFromTable2 = context2.Table2
.Where(data => data.DateChanged > yesterday)
.ToList();
var joinedData = reducedDataFromTable1
.Join(reducedDataFromTable2,
t1 => t1.Id, // Join Key on table 1
t2 => t2.T1Id, // Join Key on table 2
(table1, table2) => ... // Projection
);
However, if the data required from both databases for the join is larger than could reasonably expected to be done in memory, then you'll need to investigate alternatives, such as:
Can you do the cross database join in the database? If so, look at using a Sql projection such as a view to do the join, which you can then use in your edmx.
Otherwise, you are going to need to do the join by manually iterating the 2 enumerables, something like chunking - this isn't exactly trivial. Sorting the data in both tables by the same order will help.
Original Answer
I believe you are looking for the Linq JOIN extension method
You can join any 2 IEnumerables as follows:
var joinedData = context1.Table1
.Join(context2.Table2,
t1 => t1.Id, // Join Key on table 1
t2 => t2.T1Id, // Join Key on table 2
(table1, table2) => ... // Projection
);
Where:
Join Key on table 1 e.g. the Primary Key of Table 1 or common natural
key
Join Key on table 2, e.g. a Foreign Key or common natural key
Projection : You can whatever you want from table1 and table2, e.g.
into a new anonymous class, such as new {Name = table1.Name, Data = table2.SalesQuantity}

How this linq execute?

Data = _db.ALLOCATION_D.OrderBy(a => a.ALLO_ID)
.Skip(10)
.Take(10)
.ToList();
Let say I have 100000 rows in ALLOCATION_D table. I want to select first 10 row. Now I want to know how the above statement executes. I don't know but I think it executes in the following way...
first it select the 100000 rows
then ordered by ALLO_ID
then Skip 10
finally select the 10 rows.
Is it right? I want to know more details.
This Linq produce a SQL query via Entity Framework. Then it depends on your DBMS, but for SQL Server 2008, here is the query produces:
SELECT TOP (10) [Extent1].[ALLO_ID] AS [ALLO_ID],
FROM (
SELECT [Extent1].[ALLO_ID] AS [ALLO_ID]
, row_number() OVER (ORDER BY [Extent1].[ALLO_ID] ASC) AS [row_number]
FROM [dbo].[ALLOCATION_D] AS [Extent1]
) AS [Extent1]
WHERE [Extent1].[row_number] > 10
ORDER BY [Extent1].[ALLO_ID] ASC
You can run this in your C# for retrieve the query:
var linqQuery = _db.ALLOCATION_D
.OrderBy(a => a.ALLO_ID)
.Skip(10)
.Take(10);
var sqlQuery = ((System.Data.Objects.ObjectQuery)linqQuery).ToTraceString();
Data = linqQuery.ToList();
Second option with Linq To SQL
var linqQuery = _db.ALLOCATION_D
.OrderBy(a => a.ALLO_ID)
.Skip(10)
.Take(10);
var sqlQuery = _db.GetCommand(linqQuery).CommandText;
Data = linqQuery.ToList();
References:
How do I view the SQL generated by the entity framework?
How to: Display Generated SQL
How to view LINQ Generated SQL statements?
Your statement reads as follows:
Select all rows (overwritten by skip/take)
Order by Allo_ID
Order by Allo_ID again
Skip first 10 rows
Take next 10 rows
If you want it to select the first ten rows, you simply do this:
Data = _db.ALLOCATION_D // You don't need to order twice
.OrderBy(a => a.ALLO_ID)
.Take(10)
.ToList()
Up to the ToList call, the calls only generates expressions. That means that the OrderBy, Skip and Take calls are bundled up as an expression that is then sent to the entity framework to be executed in the database.
Entity framework will make an SQL query from that expression, which returns the ten rows from the table, which the ToList methods reads and places in a List<T> where T is the type of the items in the ALLOCATION_D collection.

Resources