I have the following code:
MyDataContext dc = new MyDataContext();
IQueryable<Table1> q1 =
from n in dc.Table1
select n
What I want to be able to do is to join a second table, so:
var qry =
from n in dc.Table1
join r in dc.Table2 on n.Key equals r.Key
select new { n, r };
This returns me a type of IQueryable<anonymous>. What I now want to do is extract Table1 and Table2. For example (this obviously doesn't work):
IQueryable<Table1> q1 = qry.Table1
IQueryable<Table2> q2 = qry.Table2
Is there a way to do this?
You want to do something like this?
IQueryable<Table1> q1 = qry.Select(x => x.n);
IQueryable<Table2> q2 = qry.Select(x => x.r);
Sure there is:
IQueryable<Table1> q1 = qry.Select(a => a.n);
IQueryable<Table2> q2 = qry.Select(a => a.r);
You can define foreign keys to your tables (on the respective keyfields) and add associations for them to your model clases (ideally via the LINQ-to-SQL designer).
Then you can do:
IQueryable<Table1> items1 = dc.Table1;
foreach (var item1 in items1)
{
var items2 = item1.Table2s; // naming might differ
}
The drawback with doing it that way, is that, even with DataLoadOptions, L2S will make this very expensive. Querying Table2 for every row in the Table1 result set.
Related
I'm using LINQ to join 2 datatables:
var JoinResult = (from p in WZdt.AsEnumerable()
join t in WZIdt.AsEnumerable()
on p.Field<string>("ID") equals t.Field<string>("ID")
select new
{
p,
t
}).ToList();
WZdt and WZIdt are DataTables. Normally, when wanted to specify columns I would write something like this:
var JoinResult = (from p in WZdt.AsEnumerable()
join t in WZIdt.AsEnumerable()
on p.Field<string>("ID") equals t.Field<string>("ID")
select new
{
FileNo = p.Field<string>("FileNo"),
Title = p.Field<string>("Title"),
M1 = t.Field<int?>("M1"),
RecCount = t.Field<int?>("RecCount")
}).ToList();
But those source datatables are created dynamically based on some logic, so they can differ when it comes to Columns they have. I would like to apply similiar logic to the select part of LINQ, but I don't know how. Can I construct array of columns somehow, like [p.FileNo, p.Title, t.M1, t.RecCount] ?
Or any other way?
I'm facing some problem with DataGridView.
I have two LINQ queries:
var query = from x in db.grupyTowarowes
where x.typ == typMoneta
select new
{
x.grupa
};
var test = from z in dbContext.Pick
join g in db.grupyTowarowes on z.Group equals g.grupa
where z.Number == 1000 && g.typ == typMoneta
select new
{
z.Group
};
And then I am setting DataSource:
dataGridView1.DataSource = test;
Query probably works correctly (don't have any errors with query) but I had some error with binding DataGridView, the error which i got is :
The query contains references do Elements defined in the context of other data.
It's weird because when I set:
dataGridView1.DataSource = query;
Then the output is correct.
Because you are using two data contexts in join (db,dbContext), But Linq does not allow join based on multiple contexts!
So you can fetch the records from one source, iterate it to join with another source;
var list1 = dbContext.Pick.ToList();
var list2 = db.grupyTowarowes.ToList();
var test = from z in list1
join g in list2 on z.ID equals g.Id
select new
{
z.A
};
Or materialize your query by using AsEnumerable will fix your issue
:
var test = from z in dbContext.Pick.AsEnumerable()
join g in db.grupyTowarowes.AsEnumerable() on z.Group equals g.grupa
where z.Number == 1000 && g.typ == typMoneta
select new
{
z.Group
};
With AsEnumerable after data is loaded, any further operation is performed using Linq to Objects, on the data already in memory.
Use ToList()
dataGridView1.DataSource = test.ToList();
Problem with your second query is, you are trying to JOIN from two different DB's as pointed below which is not possible. Better, you run each query separately and perform a LINQ - Object join to get the result
from z in dbContext.Pick
join g in db.grupyTowarowes
Try this
dataGridView1.DataSource = new BindingList<String>(test.ToList());
When I need to join some tables using linq, and when those tables consist of a lot of fields, it takes a lot of work to get all the data that I need. For instance:
var result = from i in Person
join y in Works
on i.PID euqals y.PID
join z in Groups
on y.GID on z.GID
select new {Name = i.Name, Work = y.work, WG = z.GroupName};
How can make the query return all the tables ?
I guess what you need is simply this :
var Query = from x in Table_1
join y in Table_2
on x.id equals y.id
where x.Country.Equals("X Country")
select new {x,y};
I want to join two tables and want column of both tables in result using linq
I have something like
var k = (from t in Uow.Transactions.GetAllWithReferences()
join q in Uow.TransactionDetails.GetAll() on t.TransactionId equals q.TransactionId
select t)
Instead of just t u wabt columns of both t and q
Use anonymous object to select all columns from both tables:
var k = from t in Uow.Transactions.GetAllWithReferences()
join q in Uow.TransactionDetails.GetAll()
on t.TransactionId equals q.TransactionId
select new { t.Column1, t.Column2, q.Colum3 };
Or just select both entities in anonymous object:
var k = from t in Uow.Transactions.GetAllWithReferences()
join q in Uow.TransactionDetails.GetAll()
on t.TransactionId equals q.TransactionId
select new { Transaction = t, Details = q };
Or even better - use eager loading of details. Then code will look like:
var k = Uow.Transactions.GetAllIncluding(t => t.Details);
Using lambda syntax, create anonymous result containing both items:
var joinResult = Uow.Transactions.GetAllWithReferences()
.Join(Uow.TransactionDetails.GetAll(), transaction => transaction,
details => details, (transaction, details) => new
{
Transaction = transaction,
Details = details
});
i'm starter in linq, i have write this T-SQL Query
select * from DOCUMENT_TYPES where document_id in(
select document_id from Clearance_Document where Clearance_id=(select clearance_id from clearance_id from request where request_id=3))
i want convert this T-SQL Query to linq, please help me, thanks
Well, I would start first by refactoring your SQL into something other than a chain of nested sub-queries. I think this ought to do the same thing, and it's much more readable:
SELECT
*
FROM
DOCUMENT_TYPES dt
JOIN
Clearance_Document cd
ON
dt.document_id = cd.document_id
JOIN
Request r
ON
cd.clearance_id = r.clearance_id
WHERE
r.request_id = 3
(I'm assuming that from clearance_id from request was a typo.)
Then you can easily refactor into a LINQ statement:
var result = from dt in DOCUMENT_TYPES
join cd in Clearance_Document on dt.document_id equals cd.document_id
join r in Request on cd.clearance_id equals r.clearance_id
where r.request_id = 3
select new {
property1 = dt.something,
property2 = cd.somethingElse,
...
};
var result =
from a in DOCUMENT_TYPES
let list =
(
from b in Clearance_Document
where b.Clearance_id == (from c in clearance_id where request_id == 3).First<string>())
select b
).ToList()
where list.Contains(a.document_id)
select a;
Something like that should do (i guessed you're using EF, but you can easyly adapt to other LinQ-Types):
context.Document_Types.Where(doc =>
conext.Clearance_Document.Where(cd =>
cd.Clearance_Id == context.Request.Single(r => r.Request_Id == 3)
).Contains(doc.Document_Id)
).ToList();
How about
var result = c.Id context.Request.Single(r => r.Id == 3)
.Clearances.SelectMany(c => x.DocumentTypes);
In effect, get the one and only Request with an Id equal to 3, then get all the DocumentTypes of all its Clearances.
If your database is set up with the appropriate foreign keys these relationships will be automatically generated as part of your model.