How to use a SQL query "in" linq? - c#

I have a SQL query like this:
SELECT [Id],[WfInstanceId]
FROM [WfTask]
WHERE DocId IN
(SELECT [Id]
FROM [FormInstance]
WHERE FormId = '91889C15-7205-4467-B626-3C4AAB22567B')
How can I use it with linq? I want to return an IQueryable and pass it to my grid view.

var q = from row in WfTast
where (from x in FormInstance
where FormId='91889C15-7205-4467-B626-3C4AAB22567B' &&
row.DocId = id
select x).Any()
select Id, WfInstanceId;
Or, with join:
var q = from Task in WfTast
join Form in (FormInstance.Where(x => x.FormId='91889C15-7205-4467-B626-3C4AAB22567B')
on Task.DocId = Form.Id
select Task.Id, Task.WfInstanceId;
or, Only flunet syntax:
var q = WfTast.Where(wt => FormInstance.Where(x => x.FormId='91889C15-7205-4467-B626-3C4AAB22567B' &&
wt.DocId = x.id).Any());
or:
var formsIdCollection = FormInstance.Where(x => x.FormId='91889C15-7205-4467-B626-3C4AAB22567B').Select(x => x.id);
// if you reuse this list, add at end this: .ToArray();
var q = from row in WfTast
where formsIdCollection.Contains(row.DocId)
select Id, WfInstanceId;

var query = DatabaseContext.WfTask.Where(
i => DatabaseContext.FormInstane
.Where(fi => fi.FormId = '...')
.Select(fi => fi.Id)
.Contains(i.DocId));

Related

Select const value using query expression

How can I implement this query by query expression or method expression:
Select 1, a.Id
From a
Where a.code = x
Something like this:
var data = a.Where(a => a.code == x).Select(a => new { Constant = 1, a.Id });

Convert SQL query using 'count' clause, to LinQ

My SQL Server query (below) works perfectly fine, and I'm trying to convert it to LinQ in C#.
SQL Query:
SELECT addressline3, city, COUNT(*) as 'InstitutionNumber'
FROM institutionenquiries
WHERE CITY = 'AHMEDABAD'
GROUP BY addressline3, city
ORDER BY city;
Desired output is:
I'm able to draw the LinQ query in below format, which gives me correct output
(except for COUNT(*) as 'InstitutionNumber').
LINQ Query:
var obj = (from u in dbContext.InstitutionEnquiry
where u.City == data.Trim().ToLower()
select new {
AddressLine3 = u.AddressLine3.Trim().ToLower(),
City = u.City.Trim().ToLower(),
InstitutionNumber = (from a in dbContext.InstitutionEnquiry
where a.City == data.Trim().ToLower()
select a).Count()
}).ToList();
This gives me count for 'InstitutionNumber' = 3 for all.
I'm not able to get the count aspect correctly. I've referred to this post's answer and it gives me only count, but I'm not able to nest it within my LinQ query.
Any helpful inputs will be appreciated.
The first observation is that since SQL has a GROUP BY, LINQ should have a GroupBy, too.
The second observation is that since non-aggregate columns in SQL are group by columns, the results you select in LINQ would come from the group's key.
Now we can write the query:
var res = dbContext.InstitutionEnquiry
.Where(u => u.City == data.Trim().ToLower())
.GroupBy(u => new {
AddressLine3 = u.AddressLine3.Trim().ToLower(),
City = u.City.Trim().ToLower()
}).Select(g => new {
g.Key.AddressLine3,
g.Key.City,
Count = g.Count()
}).ToList();
I think you can use this LinQ :
var obj = dbContext.InstitutionEnquiry
// WHERE CITY = 'AHMEDABAD'
.Where(w => w.City == "AHMEDABAD") // => Note
// GROUP BY addressline3, city
.GroupBy(g => new {g.AddressLine3, g.City})
// SELECT addressline3, city, COUNT(*) as 'InstitutionNumber'
.Select(c => new {c.Key.AddressLine3, c.Key.City, InstitutionNumber = c.Count()})
// ORDER BY city
.OrderBy(o=> o.City)
.ToList();
Note: For ignoring case sensitivity You can use :
.Where(string.Equals(w.City.Trim(), data.Trim(), StringComparison.CurrentCultureIgnoreCase))
LINQ :
var obj = (from p in dbContext.InstitutionEnquiry
group p by new
{
p.addressline3,
p.city
} into grp
select new
{
grp.Key.addressline3,
grp.Key.city,
InstitutionNumber = grp.Count(),
}).ToList();
Equivalent Lambda expression :
var obj = dbContext.InstitutionEnquiry
.GroupBy(p => new { p.addressline3, p.city})
.Select(p => new { p.Key.addressline3, p.Key.city, InstitutionNumber = p.Count() })
.ToList();

SUM and COUNT in single LINQ to SQL query

I'm trying to create the following query in LINQ-TO-SQL.
select count(*), sum( o.CostInCents ) from Orders o
where Flag = true;
I came up with the following LINQ query:
var q = db.Orders
.Where(o => o.Flag )
var result = q
.GroupBy(o => 1)
.Select(g => new MyDTO
{
NoOfOrders = g.Count(),
TotalInCents = g.Sum(o => o.CostInCents )
})
.SingleOrDefaultAsync();
Is there a better way?
Is .GroupBy(o => 1) even OK?
The other option would be to do two queries, like below.
var q = db.Orders
.Where(o => o.Flag );
//No groupBy
var result2 = new MyDTO
{
NoOfCostedOrders = q.Count(),//hit the db
TotalInCents = q.Sum(o => o.CostInCents )//hit the db 2nd time
};
How should I judge which approach is better?
Thanks in advance!
This query can be rewritten in sql format as follows
var orderList = db.Orders.Where(o => o.Flag );
var orderSummary = from o in orderList
group o by 1 into p
select new
{
Items = p.Count(),
Total = p.Sum( x => x.CostInCents)
}
I think what you are searching for is the following slight adjustment:
var q = db.Orders
.Where(o => o.Flag).Select(o => o.CostInCents).ToList(); // hit the db here once
//No groupBy
var result2 = new MyDTO
{
NoOfCostedOrders = q.Count(), // don't hit the db
TotalInCents = q.Sum() // don't hit the db a 2nd time
};
If you have a question to my adjustment feel free to comment.

C# lambda-> All rows Select Add Row_Number

I have a table:
DataTable store_temp = new DataTable();
store_temp.Columns.Add("patn");
store_temp.Columns.Add("rf");
store_temp.Columns.Add("name");
store_temp.Columns.Add("conv");
store_temp.Columns.Add("conv_type");
store_temp.Columns.Add("recorddate");
store_temp.Columns.Add("executiondate");
My C# code :
int i = 0;
var rowsgroups = (from row in store_temp.AsEnumerable().GroupBy(row =>
row.Field<string>("patn"))
.OrderBy((g => g.OrderByDescending(y => y.Field<string("executiondate")).ThenByDescending(y =>
y.Field<string>("rf"))))
select new
{
patn = row.ElementAt(i),
rf_num = ++i,
}).ToArray();
I want the lambda experession, which is equivalent to:
select patn, rf,
> row_number() over( partition by patn order by executiondate,rf )
as rf_num,
name, conv,conv_type, recorddate, executiondate
from store_temp2
But, lambda syntax ... var rowsgroups has just a one row..
I want to show all rows in store_temp.
What should I do to fix the query?
row_number() over(partition by patn order by executiondate, rf)
means in LINQ you need to group by patn, then order each group by executiondate, rf, then use the indexed Select overload to get row numbering inside the group, and finally flatten the result with SelectMany.
With that being said, the equivalent LINQ query could be something like this:
var result = store_temp.AsEnumerable()
.GroupBy(e => e.Field<string>("patn"), (key, elements) => elements
.OrderBy(e => e.Field<string>("executiondate"))
.ThenBy(e => e.Field<string>("rf"))
.Select((e, i) => new
{
patn = key,
rf = e.Field<string>("rf"),
rf_num = i + 1,
name = e.Field<string>("name"),
conv = e.Field<string>("conv"),
conv_type = e.Field<string>("conv_type"),
recorddate = e.Field<string>("recorddate"),
executiondate = e.Field<string>("executiondate")
}))
.SelectMany(elements => elements)
.ToArray();
Try something like this
select new
{
rowNum = store_temp.Rows.IndexOf(row),
patn = row.ElementAt(i),
rf_num = ++i,
}).ToArray();
I don't think you required any groupby as per your required sql
var i=0;
var rowsgroups = (from row in store_temp.AsEnumerable()
orderby row.Field<string>("executiondate") descending,
row.Field<string>("rf") descending
select new
{
patn = row.Field<string>("patn"),
rf_num = ++i,
name = row.Field<string>("name"),
conv = row.Field<string>("conv"),
conv_type = row.Field<string>("conv_type"),
recorddate = row.Field<string>("recorddate"),
executiondate = row.Field<string>("executiondate")
}).ToArray();

Need help for a more beautiful LINQ to SQL query

Following is a T_SQL query for AdventureWorks database:
SELECT Name
FROM Production.Product
WHERE ListPrice >= ANY
(SELECT MAX (ListPrice)
FROM Production.Product
GROUP BY ProductSubcategoryID)
I try writing a LINQ query for this:
var groupMaxPricesquery2 = from product in dc.Products
group product by product.ProductSubcategoryID into productGroup
select productGroup.Max(eachProductInGroup => eachProductInGroup.ListPrice);
var query = from product in dc.Products
where groupMaxPricesquery2.Any(listPrice => listPrice <= product.ListPrice)
select product.Name;
How can I make it more beautiful (i.e. combining those queries together, or a more efficient approach)?
Thank you very much
Give either of these a try:
var query = from product in dc.Products
let groupMaxPricesQuery = dc.Products.GroupBy(p => p.ProductSubcategoryID)
.Select(g => g.Max(item => item.ListPrice))
where groupMaxPricesQuery.Any(listPrice => listPrice <= product.ListPrice)
select product.Name;
// or
var query = dc.Products
.Select(product => new {
Product = product,
GroupedMaxPrices = dc.Products.GroupBy(p => p.ProductSubcategoryID)
.Select(g => g.Max(item => item.ListPrice))
})
.Where(item => item.GroupedMaxPrices.Any(listPrice => listPrice <= item.Product.ListPrice))
.Select(item => item.Product.Name);
Maybe I'm missing something with the grouping, but I don't see why it is necessary.
var maxListPrice = dc.Products.Max(p => p.ListPrice);
var query = dc.Products.Where(p => p.ListPrice >= maxListPrice).Select(n => n.Name);

Categories