I am trying to write dynamic Linq Library query to fetch record on condition,
Customers who has order count is greater than 3 and ShipVia field equal 2.
Below is my syntax what i have tried.
object[] objArr = new object[10];
objArr[0] = 1;
IQueryable<Customer> test = db.Customers.Where("Orders.Count(ShipVia=2)", objArr);
and
IQueryable<Customer> test = db.Customers.Where("Orders.Any(ShipVia=2).Count()", objArr);
But both are not working. In second query Any returns true so it won't work with Count.
Suggest me a way to implement this.
If you HAVE to use Dynamic Linq, your query should look like that:
db.Customers.Where("Orders.Count(ShipVia == 2) > 3");
How about something like this.
IQueryable<Customer> test = db.Customers.Where(c => c.Orders.Where(o => o.ShipVia ==2).Count() >2);
var grp = db.Customers.Where("ShipVia=2").GroupBy("ShipVia");
var test = from a in grp
where a.Count() > 3
select a.Key;
IQueryable<Customer> test =
from c in db.Customers
from o in c.Orders
where o.ShipVia == 2 // NOTE you need == not = for compare
group c by c into grp
select new {customer = grp.key, ordercount = grp.Count() };
Untested but I believe this should do it all in one statement, assuming Orders are a collection within Customer.
Note that your single = in your where clause is very dangerous as it'll assign 2 to all shipvias instead of test (==)
Related
how can i convert rows to column in entity framework!?
i have a result like this:
and i want this result:
my entity code i this :
(from loanPerson in context.LoanPersons.AsParallel()
join warranter in context.Warranters.AsParallel() on loanPerson.Id equals warranter.LoanPersonId
where loanPerson.Id == 84829
select new
{
loanPersonId = loanPerson.Id,
waranterId = warranter.WarranterPersonID,
}).ToList();
and number of the row always less than 3 and i want to have 3 column.
please let me know your answer.
tanks.
This query will return the only one row, where waranterIds will contain, at this particular case, three WarranterPersonID values, also this field is of List<int> type, because it's quantity not known at compile time:
var answer = (from loanPerson in context.LoanPersons.Where(x => x.Id == 84829)
join warranter in context.Warranters
on loanPerson.Id equals warranter.LoanPersonId
group warranter by loanPerson.Id into sub
select new
{
loanPersonId = sub.Key,
waranterIds = sub.Select(x => x.LoanPersonId).ToList()
//if you sure, that quantity equals 3,
//you can write this code instead of waranterIds:
//zamen1 = sub.Select(x => x.LoanPersonId).First(),
//zamen2 = sub.Select(x => x.LoanPersonId).Skip(1).First(),
//zamen3 = sub.Select(x => x.LoanPersonId).Skip(2).First()
}).ToList();
I'm completely new to LINQ, i want to rewrite some of mine SQL querys into LINQ (just to learn) and i'v already stuck at the beginning. Probably solution is very simple but as i'v said I'm completely new and i didn't find solution to this.
I have one query :
string typMoneta = textBox1.Text;
var moneta = from x in db.grupyTowarowes
where x.typ == typMoneta
select new
{
x.grupa
};
Which works ok and when i set
dataGridView1.DataSource = moneta;
Then i got output
And i want to use this output in my second query :
var query = from c in dbContext.Picking
where c.Number == 1000 && c.Group == moneta
select new
{
c.id
};
Problem is with c.Group == moneta. I don't know the correct syntax. Could someone help me?
I think you meant to use moneta.Contains(c.Group). In first query, make sure you use ToList() to load data into memory.
IList<string> moneta = (from x in db.grupyTowarowes
where x.typ == typMoneta
select x.grupa).ToList();
var query = (from c in dbContext.Picking
where c.Number == 1000 && moneta.Contains(c.Group)
select c.id).ToList();
The moneta is an IEnumerable<T> where T in your case is the type of grupa
That being said you should write your query like below:
var query = from c in dbContext.Picking
where c.Number == 1000
&& moneta.Contais(c.Group)
select new
{
c.id
};
or in fluent syntax like below:
var query = dbContext.Picking
.Where(pick => pick.Number == 1000
&& moneta.Contains(pick.Group))
.Select(pick => pick.id);
Note that moneta is not a collection of strings. It's a collection of objects that have a string property named "grupa".
Does this work for you?
var query =
from c in dbContext.Picking
where c.Number == 1000
&& moneta.Any(m => m.grupa == c.Group)
select new { c.id };
You could also do this:
// Get list of strings
var groups = moneta.Select(m => m.grupa).ToList();
// Get items where "Group" value is one of the strings in groups list, above.
var query =
from c in dbContext.Picking
where c.Number == 1000
&& groups.Contains(c.Group)
select new { c.id };
Hello I have the following linq statement:
IEnumerable<TabTransaktion> allTransactions
= TabTransaktions1.Union(TabTransaktions2)
.Where(trans => trans.TabVorgang != null).
.OrderBy(tran => tran.TabVorgang.Wirkdatum)
.OrderByDescending(trans2 => trans2.TabVorgang.ID);
But I want the second order by descending when only trans2.TabVorgang.ID equals to 0. So I need a "case" in "order by clause" for LinQ. A LinQ equivalent of something like this:
SELECT BusinessEntityID, SalariedFlag
FROM HumanResources.Employee
ORDER BY CASE SalariedFlag WHEN 1 THEN BusinessEntityID END DESC
,CASE WHEN SalariedFlag = 0 THEN BusinessEntityID END;
GO
I would appreciate any help.
Assuming SalariedFlag is a bool (in SQL of type bit), the two ordering expressions are exclusively mutual. In other words, the main query can be separated into two disjunctive queries and the final result is the union of them:
IEnumerable<TabTransaktion> mainQuery
= TabTransaktions1.Union(TabTransaktions2)
.Where(trans => trans.TabVorgang != null);
var queryOne = mainQuery.Where(p=>p.SalariedFlag ==1)
.OrderByDescending(tran => tran.BusinessEntityID );
var queryTwo = mainQuery.Where(p=>p.SalariedFlag ==0)
.OrderBy(tran => tran.BusinessEntityID);
var finalResult = queryOne.Union(queryTwo);
I have a query that looks like this: it takes a list of IDs (ThelistOfIDs) as parameter and I'm grouping for a count.
var TheCounter = (from l in MyDC.SomeTable
where ThelistOfIDs.Contains(l.ID)
group l by l.Status into groups
select new Counter()
{
CountOnes = (from g in groups
where g.Status == 1
select g).Count(),
CountTwos = (from g in groups
where g.Status == 2
select g).Count(),
}).Single();
And basically, I don't understand why I'm getting the error. I don't want to brring back the entore collection from the DB and do the count in linq-to-object; I want to do the count in the DB and bring back the result.
I have not put your query into my IDE or compiled with C#, but I guess the problem is that
groups in your query is IGrouping<Tkey, Telm> and not IQueryable<Tkey>
(where Tkey is type of l.Status and Telm is type of l).
I think you got confused with the use of grouping operator.
What you want to get is I guess:
var queryByStatus = from l in MyDC.SomeTable
where ThelistOfIDs.Contains(l.ID)
group l by l.Status;
var counter = new Counter()
{
CountOnes = queryByStatus.Where(l => l.Key == 1).Count(),
CountTwos = queryByStatus.Where(l => l.Key == 2).Count(),
};
EDIT:
Alternative query, to obtain the same, moving all operation on DB into the original query so that DB is queried only once.
var queryCountByStatus = from l in MyDC.SomeTable
where ThelistOfIDs.Contains(l.ID)
group l by l.Status into r
select new { status = r.Key, count = r.Count() };
var countByStatus = queryCountByStatus.ToList();
var counter = new Counter()
{
CountOnes = countByStatus.FirstOrDefault(l => l.status == 1).count,
CountTwos = countByStatus.FirstOrDefault(l => l.status == 2).count,
};
Note:
The query in my edit section queries the DB once only and mapping Status -> Count is returned.
Note that in my original query there were two calls to DB needed only - both of which returned single number - one for CountOnes, one for CountTwos.
In the edit query, one query is done which return table { { 1, CountOnes}, {2, CountTwos } }. The other lines are just to convert the result - which is set of items - into single object having certain objects as properties and is done physically on these two values.
You are grouping by Status, and then projecting from that group - but you will still have one row per unique Status (===group).
So: I propose that you don't have exactly one unique Status.
This might be what you're looking for to get...
(it's for users table I had but should be the same)
var statuscounts = (from u in db.Users
where u.UserStatus > 0
group u by u.UserStatus into groups
select new { Status = groups.Key, Count = groups.Count() });
// do this to iterate and pump into a Counter at will
foreach (var g in statuscounts)
Console.WriteLine("{0}, {1}", g.Status, g.Count);
...or even something like this...
var counter = statuscounts.AsEnumerable()
.Aggregate(new Counter(), (c, a) => {
switch (a.Status)
{
case 1: c.CountOfOnes = a.Count; return c;
case 2: c.CountOfTwos = a.Count; return c;
case 3: c.CountOfThrees = a.Count; return c;
default: c.CountOfOthers = a.Count; return c;
}});
...point is that if you're grouping already you should use the grouping result, it's of type IGrouping<out TKey, out TElement> where the key is your status and it's IEnumerable<> or your records.
hope this helps
I have a small problem in my where clause in the linq expression below. If I put the number 3 instead of department.Id I get the desired result but when I use department.Id I get nothing in the resultset.
I also want to get a count for the number of filters for that filter name using the query again using distinct.
var dept = Page.RouteData.Values["department"];
var department = (from d in db.Departments
where d.Name.Replace(" ", "-") == dept
select new {d.Id, d.Name}).FirstOrDefault();
var query = from p in db.Products
join f in db.ProductFilters on p.Id equals f.ProductId into filters
from x in filters.Where(x => x.Product.DepartmentId == department.Id
/* if == 3 it works */)
select new { x.Name, x.Id };
Promoted to answer from comments:
Have you checked that the department instance is as you think it should be after the first linq statement - ie has an Id == 3?
Your first query is not finding any valid department and is therefore returning default which most probably means that departmend.Id == 0.