How to nested parsing expression ,I'm developing an ORM, who can help me with some ideas?
var list = db.Queryable<Student>()
.Where(it => it.Id.Equals(db.Queryable<School>()
.Where(sc => sc.Id == it.Id&&sc.Name=="jack"))).ToList()
It's batter to use LINQ joins for this purpose.
Example:
1| LINQ query-syntax
var list = (from s in db.Student
join sc in db.School on s.SchoolId equals sc.Id
where sc.Name=="jack"
select s).ToList() ;
2| LINQ Extension method
var list = db.Student.Join(db.School,
s => s.SchoolId,
sc => sc.Id,
(s, sc) => new { s, sc })
.Where(ss => ss.sc.Name=="jack")
.Select(ss => ss.s).ToList();
You can get more information about query-syntax and Extension method in this answer.
Related
var model = _db.Seuni
.Join(from o in _db.Keuni
join
c in _db.Seuni
on o.klasaid equals c.klasaid
select new {o.emriklases,c.emristudent,c.studentid,c.nota })
.OrderByDescending(r => r.nota)
I have this sample of code,I have searched to find the right syntax for this linq extension method ,and I haven't can sb give to me the right one?Thank You in advance
You have mixed query and method syntax in a wrong way.
var model = _db.Seuni
.Join(_db.Keuni,
c => c.klasaid,
o => o.klasaid,
(c, o) => new { o.emriklases, c.emristudent, c.studentid, c.nota })
.OrderByDescending(r => r.nota);
Or with query (method for order) syntax
// query syntax
var model = (from o in _db.Keuni
join c in _db.Seuni on o.klasaid equals c.klasaid
select new { o.emriklases, c.emristudent, c.studentid, c.nota })
.OrderByDescending(r => r.nota);
I want to pick up all Sellers that aren't boss of a department.
How can I make this? In this query below, only the Sellers that are bosses of a department are picked up, I want the opposite of thereof.
My query:
var query = db.Sellers
.Join(db.Departments,
s => s.Id,
d => d.BossId,
(s, d) => new { Seller = s, Department = d })
.Where(a => a.Seller.Id == a.Department.BossId) ????
.Select(x => x.Seller).ToList();
In the "Where" part, I tried a => a.Seller.Id != a.Department.BossId, but it's wrong I have 3 sellers that aren't bosses.
I tried with this way too:
var listNonBoss = (from s in db.Sellers
join d in db.Departments on s.Id equals d.BossId
select s.Id).ToList();
I want just the opposite of these queries.
Sometimes it's easier to break it into multiple steps.
First, get the collection of all boss IDs:
var bossIDs = db.Departments.Select(x => x.BossId);
Then get all sellers whose IDs are not in that collection:
var listNonBoss = db.Sellers.Where(x => !bossIDs.Contains(x.Id)).ToList();
Join in your code will do an inner join, meaning it'll filter out sellers who don't have a boss.
To do the opposite you can do an outer join, and then remove the ones who have a boss. In fluent LINQ an outer join is done by doing a GroupJoin and then SelectMany.
Something like this:
var query = db.Sellers
.GroupJoin(db.Departments, s => s.Id, d => d.BossId, (s, d) => new { Seller = s, Department = d })
.SelectMany(x => x.d.DefaultIfEmpty(), (seller, department) => new { s.seller, department})
.Where(a => a.department.BossId == null)
.Select(x => x.Seller).ToList();
Or, using query syntax:
var listNonBoss = (from s in db.Sellers
join d in db.Departments on s.Id equals d.BossId into joinedTable
from jt in joinedTable.DefaultIfEmpty()
where jt.BossId == null
select s.Id).ToList();
I have a simple LINQ lambda join query but I want to add a 3rd join with a where clause. How do I go about doing that?
Here's my single join query:
var myList = Companies
.Join(
Sectors,
comp => comp.Sector_code,
sect => sect.Sector_code,
(comp, sect) => new {Company = comp, Sector = sect} )
.Select( c => new {
c.Company.Equity_cusip,
c.Company.Company_name,
c.Company.Primary_exchange,
c.Company.Sector_code,
c.Sector.Description
});
I want to add the following SQL command to the above LINQ query and still maintain the projections:
SELECT
sector_code, industry_code
FROM
distribution_sector_industry
WHERE
service = 'numerical'
The 3rd join would be made with Sector table & Distribution_sector_industry on sector_code.
Thanks in advance.
Just a guess:
var myList = Companies
.Join(
Sectors,
comp => comp.Sector_code,
sect => sect.Sector_code,
(comp, sect) => new { Company = comp, Sector = sect })
.Join(
DistributionSectorIndustry.Where(dsi => dsi.Service == "numerical"),
cs => cs.Sector.Sector_code,
dsi => dsi.Sector_code,
(cs, dsi) => new { cs.Company, cs.Sector, IndustryCode = dsi.Industry_code })
.Select(c => new {
c.Company.Equity_cusip,
c.Company.Company_name,
c.Company.Primary_exchange,
c.Company.Sector_code,
c.Sector.Description,
c.IndustryCode
});
Okay, I can't see why you'd want to select sector_code when you already know it, but I think you want this:
var query = from company in Companies
join sector in Sectors
on company.SectorCode equals sector.SectorCode
join industry in DistributionSectorIndustry
on sector.SectorCode equals industry.SectorCode
where industry.Service == "numerical"
select new {
company.EquityCusip,
company.CompanyName,
company.PrimaryExchange,
company.SectorCode,
sector.Description,
industry.IndustryCode
};
Notes:
I've changed it into a query expression as that's a much more readable way of expressing a query like this.
Although the "where" clause comes after the join, assuming this is a LINQ to SQL or Entity Framework query, it shouldn't make any difference
I've lengthened the range variable names for clarity
I've converted your other names into conventional .NET names; you can do this too in your model
For 4 Tables
var query = CurrencyDeposits
.Join(Customers, cd => cd.CustomerId, cus => cus.Id, (cd, cus)
=> new { CurrencyDeposit = cd, Customer = cus })
.Join(Currencies, x => x.CurrencyDeposit.CurrencyId, cr => cr.Id, (x, cr)
=> new { x.CurrencyDeposit, x.Customer, Currency = cr })
.Join(Banks, x => x.CurrencyDeposit.BankId, bn => bn.Id, (x, bn)
=> new { x.CurrencyDeposit, x.Customer, x.Currency, Bank = bn})
.Select(s => new {
s.CurrencyDeposit.Id,
s.Customer.NameSurname,
s.Currency.Code,
s.Bank.BankName,
s.CurrencyDeposit.RequesCode
});
Try something like this...
var myList = ({from a in Companies
join b in Sectors on a.Sector_code equals b.Sector_code
join c in Distribution on b.distribution_code equals a.distribution_code
select new {...});
Consider a SQL Server table that's used to store events for auditing.
The need is to get only that latest entry for each CustID. We want to get the entire object/row. I am assuming that a GroupBy() will be needed in the query. Here's the query so far:
var custsLastAccess = db.CustAccesses
.Where(c.AccessReason.Length>0)
.GroupBy(c => c.CustID)
// .Select()
.ToList();
// (?) where to put the c.Max(cu=>cu.AccessDate)
Question:
How can I create the query to select the latest(the maximum AccessDate) record/object for each CustID?
I'm wondering if something like:
var custsLastAccess = db.CustAccesses
.Where(c.AccessReason.Length>0)
.GroupBy(c => c.CustID)
.Select(grp => new {
grp.Key,
LastAccess = grp
.OrderByDescending(x => x.AccessDate)
.Select(x => x.AccessDate)
.FirstOrDefault()
}).ToList();
you could also try OrderBy() and Last()
Using LINQ syntax, which I think looks cleaner:
var custsLastAccess = from c in db.CustAccesses
group c by c.CustID into grp
select grp.OrderByDescending(c => c.AccessDate).FirstOrDefault();
Here: this uses max rather than OrderByDesc, so should be more efficient.
var subquery = from c in CustAccesses
group c by c.CustID into g
select new
{
CustID = g.Key,
AccessDate = g.Max(a => a.AccessDate)
};
var query = from c in CustAccesses
join s in subquery
on c.CustID equals s.CustID
where c.AccessDate == s.AccessDate
&& !string.IsNullOrEmpty(c.AccessReason)
select c;
Does anyone know how to write this
var q = from c in customers
join o in orders on c.Key equals o.Key
select new {c.Name, o.OrderNumber};
In this syntax style?
var 1= customers.
.join(???)
.select(???)
I've been googling for a way to do this for days now with now luck. Everyone preferes the first syntax for tutorials, but I find the second much easier to determine order of operation when reading.
The compiler translation process involves using a "transparent identifier" that makes the current customer and order available to the Select method. You can emulate this by making your own:
customers.Join(orders, c => c.Key, o => o.Key, (c, o) => new { c, o })
.Select(x => new { x.c.Name, x.o.OrderNumber });
Instead, you could just move your Name/OrderNumber projection up into the Join call:
customers.Join(orders, c => c.Key, o => o.Key, (c, o) => new { c.Name, o.OrderNumber });
This just takes a single call to Enumerable.Join:
var q = customers.Join(
orders,
c => c.Key,
o => o.Key,
(c, o) => new {c.Name, o.OrderNumber}
);
You might also check out LinqPad . It has a small lambda button for the bottom half of the screen, and it translates the linq query to chain methods :
from p in PropertyListings
from rl in p.ResidentialListings
select new {p.YearBuilt,p.ListingUrl}
got translated to :
PropertyListings
.SelectMany (
p => p.ResidentialListings,
(p, rl) =>
new
{
YearBuilt = p.YearBuilt,
ListingUrl = p.ListingUrl
}
)