How to write LINQ query row numbers in C#? [duplicate] - c#

This question already has answers here:
How do you add an index field to Linq results
(3 answers)
Closed 3 years ago.
SQL:
Select top percent a,b,ROW_NUMBER() over(PARTITION BY a,b order by a,b) as rowsnumber
from Students as s
group by a,b
LINQ:
var students=from p in Students
group p by new{p.a,p.b} into grp
order by grp.Key.a,grp.Key.b
.Select(s=>s.a,s.b).ToList();
I want to this SQL query convert to LINQ but not convert.

var list = FileList.Select((file, index) => new { Index=index, Filename=file });
Maybe so for example.

Like the other answer indicates, the Select method has a handy overload with the index parameter. It requires the method LINQ syntax though (and not the query syntax) So, the following query should do the trick. Note that it combines both: query and method syntax as I tried to keep it close to the code in the question above.
var studentGroups=
from p in Students
group p by new { p.a, p.b };
var students =
from gr in studentGroups
from st in Students
.Where(s => s.a == gr.Key.a && s.b == gr.Key.b)
.Select((s,i) => new { s.a, s.b, s.c, s.d, rn = i + 1 })
orderby st.a, st.b
select st;

I convert your sql query to lambda.
var students = context.GroupBy(g => new { g.A, g.B }).Select((s, index) => new {
s.Key.A,
s.Key.B,
rowsnumber = index + 1
}).Take(10).ToList();
Group by is working like partition by.
Index start from 0, so converting to row number to need add 1.
Take is select TOP 10 rows.

Related

how to pass parameters to LINQ where condition dynamically [duplicate]

This question already has answers here:
C# Linq where clause as a variable
(5 answers)
Closed 4 years ago.
Im new in LINQ,i need to pass different conditions on the same LINQ query like:
var rslt = (from t in cr.faultStat
where(parameter)
select new{
name=t.Name,
Fname=t.fname
});
the parameter seen in the where ,is the part i want to send conditions dynamicaly but i dont know how,because where accepts boolean,but i want to send something like:
string parameter="date>"2018-10-10" && id="123"
generally how should i send parameter to linq dynamically
I guess (according to your comment) actually you don't have a string but you have multiple conditions. Then i'd suggest to write your query like this:
var query = cr.faultStat;
// the user selected a min-date-filter?
if(minDate.HasValue)
{
query = query.Where(x => x.Date > minDate.Value);
}
// the user selected a max-date-filter?
if(maxInclusiveDate.HasValue)
{
query = query.Where(x => x.Date <= maxInclusiveDate.Value);
}
// the user selected an id-filter?
if(id.HasValue)
{
query = query.Where(x => x.Id == id.Value);
}
var rslt = query
.Select(x => select new
{
t.name,
t.fname, ...
});
Actually after this the database (or whatever the source is) was not even queried once due to deferred execution of above methods. You have to use a foreach or a method that does it:
int resultCount = rslt.Count(); // like this

How to give conditional where clause in a single linq query? [duplicate]

This question already has answers here:
Linq: adding conditions to the where clause conditionally
(9 answers)
Closed 6 years ago.
I have a query, which will give the result set . based on a condition I want to write the where clause. that means . I have a variable x, if the value of x is "ALL" then I don't want to add this condition at all.if the value is not "ALL" then I need to add a where clause (where st.address==x). how can I add this condition in below query .
var abc=(from st in Context.STopics join ap in Context.ATopic on st.id equals ap.id
where st.address==x
select new result()
{
name = st.name
add= ap.add}).ToList();
Here is what you're looking for:
var yourQuery = Context.STopics.AsQueryable();
var yourParam = "ALL";
if(yourParam != "ALL")
yourQuery = yourQuery.Where(x => x.IsActive==true && x.StudentID == 123);
var abc = yourQuery.Select(x=> new result()
{
name = st.name
}).ToList();
The thing is that with linQ you don't get your data from query right away. So you can construct your actual query this way as you need.
You can make your condition in a way that matches all elements when x = "ALL" and otherwise match your other conditions:
var abc=(from st in Context.STopics
where x == "ALL" || (st.IsActive==true && st.StudentID == 123)
select new result()
{
name = st.name }).ToList();
Something like:
var abc=(from st in Context.STopics
where (x!="All" ? (st.IsActive==true && st.StudentID == 123) )
select new result()
{
name = st.name
}).ToList();

different results between Linq and SQL

i don't know why i get different results between this SQL and LINQ
Could you like to tell me why...?
SQL:
select distinct top 50 (id) as d_id
from talbe1
where id<>-1
order by d_id asc;
Linq:
IList<int> myResults =
(from t in dbconn.table1
where t.id != -1
orderby t.id ascending
select t.id
).Distinct().Take(50).ToList();
int callCnt = 0;
foreach (int row in myResults)
{
callCnt++;
Console.WriteLine(callCnt.ToString() + " " + row.ToString() );
}
The SQL get the results i want,
but the Linq result is like :
1 72662
2 84945
3 264577
4 77655
5 71756
6 76899
7 76719
8 77669
9 152211
10 79168
11 72334
12 71399
13 246031
14 80748
15 77715
.......
This is a limitation of LINQ to SQL, where the OrderBy() must occur after the Distinct(), try this:
IList<int> myResults =
(from t in dbconn.table1
where t.id != -1
select t.id
).Distinct().OrderBy(t => t).Take(50).ToList();
The problem is the way that the Distinct() method works. Unfortunately it can (and usually does) change the order of the items in the list. You need to order the list after calling Distinct().
Try this:
IList<int> myResults =
(
from t in dbconn.table1
where t.id != -1
select t.id
).Distinct().OrderBy(i => i).Take(50).ToList();
Try
var myResults = dbconn.Table1.Where(e => e.id != -1).Select(e => e.id).Distinct()
.OrderBy(t => t).Take(50).ToList();

Linq To Entities

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.

Count occurrences of values across multiple columns

I am having a terrible time finding a solution to what I am sure is a simple problem.
I started an app with data in Lists of objects. It's pertinent objects used to look like this (very simplified):
class A {
int[] Nums;
}
and
List<A> myListOfA;
I wanted to count occurrences of values in the member array over all the List.
I found this solution somehow:
var results
from a in myListOfA
from n in a.Nums
group n by n into g
orderby g.Key
select new{ number = g.Key, Occurences = g.Count}
int NumberOfValues = results.Count();
That worked well and I was able to generate the histogram I wanted from the query.
Now I have converted to using an SQL database. The table I am using now looks like this:
MyTable {
int Value1;
int Value2;
int Value3;
int Value4;
int Value5;
int Value6;
}
I have a DataContext that maps to the DB.
I cannot figure out how to translate the previous LINQ statement to work with this. I have tried this:
MyDataContext myContext;
var results =
from d in myContext.MyTable
from n in new{ d.Value1, d.Value2, d.Value3, d.Value4, d.Value5, d.Value6 }
group n by n into g
orderby g.Key
select new { number = g.Key, Occurences = g.Count() };
I have tried some variations on the constructed array like adding .AsQueryable() at the end - something I saw somewhere else. I have tried using group to create the array of values but nothing works. I am a relative newbie when it come to database languages. I just cannot find any clue anywhere on the web. Maybe I am not asking the right question. Any help is appreciated.
I received help on a microsoft site. The problem is mixing LINQ to SQL with LINQ to Objects.
This is how the query should be stated:
var results =
from d in MyContext.MyTable.AsEnumerable()
from n in new[]{d.Value1, d.Value2, d.Value3, d.Value4, d.Value5, d.Value6}
group n by n into g
orderby g.Key
select new {number = g.Key, Occureneces = g.Count()};
Works like a charm.
If you wish to use LINQ to SQL, you could try this "hack" that I recently discovered. It isn't the prettiest most cleanest code, but at least you won't have to revert to using LINQ to Objects.
var query =
from d in MyContext.MyTable
let v1 = MyContext.MyTable.Where(dd => dd.ID == d.ID).Select(dd => dd.Value1)
let v2 = MyContext.MyTable.Where(dd => dd.ID == d.ID).Select(dd => dd.Value2)
// ...
let v6 = MyContext.MyTable.Where(dd => dd.ID == d.ID).Select(dd => dd.Value6)
from n in v1.Concat(v2).Concat(v3).Concat(v4).Concat(v5).Concat(v6)
group 1 by n into g
orderby g.Key
select new
{
number = g.Key,
Occureneces = g.Count(),
};
How about creating your int array on the fly?
var results =
from d in myContext.MyTable
from n in new int[] { d.Value1, d.Value2, d.Value3, d.Value4, d.Value5, d.Value6 }
group n by n into g
orderby g.Key
select new { number = g.Key, Occurences = g.Count() };
In a relational database, such as SQL Server, collections are represented as tables. So you should actually have two tables - Samples and Values. The Keys table would represent a single "A" object, while the Values table would represent each element in A.Nums, with a foreign key pointing to the one of the records in the Samples table. LINQ to SQL
's O/R mapper will then create a "Values" property for each Sample object, which contains a queryable collection of the attached Values. You would then use the following query:
var results =
from sample in myContext.Samples
from value in sample.Values
group value by value into values
orderby values.Key
select new { Value = values.Key, Frequency = values.Count() };

Categories