I am trying to write a SQL subquery in linq - linq

I am trying to write a subquery in linq here is my SQL script
Select id, name from employee where id in (select dictinct id in salaryEmp)
I have tried several combination but not getting the desired output. I will appreciate any help in this regards

This should do it:
db.employee
.Where(x => salaryEmp.Select(x => x.id).Distinct().Contains(x.id))
.Select(x => new { x.id, x.name });
Or better you can do:
var idList = salaryEmp.Select(x => x.id).Distinct().ToList();
var result = db.employee
.Where(x => idList.Contains(x.id))
.Select(x => new { x.id, x.name });

You didn't say how your context looks like, but it will be something like that:
from e in ctx.employee
where
(from s in ctx.salaryEmp
select s.Id).Distinct().Contains(e.id)
select new { e.Id, e.Name }
or with sub query as method-based query:
from e in ctx.employee
where ctx.salaryEmp.Select(s => s.Id).Distinct().Contains(e.id)
select new { e.Id, e.Name }

Related

How to make oData case insensitive when query calls AsEnumerable?

Since .NET Core 3 we can no longer use GroupBy without calling AsEnumerable or ToList first.
The problem with calling AsEnumerable is that it makes the oData queries case sensitive. This filter with 'aaaa' does not find 'A' for instance:
https://localhost/myweb.api/api/mymethod?$filter=contains(Name,%20%27aaaa%27)
How can I make this case insensitive again?
this is not production code, just an example:
public IQueryable<Dto> GetDto(
{
return (from a in _context.Names
select new Dto
{
Name = a.Name
})
.AsEnumerable() // this is needed for the group by to work
.GroupBy(x => new { x.Name })
.Select(x => new Dto
{
Name = x.Key.Name
})
.AsQueryable();
}
You can try with same cases by making .tolower() or .toUpper() and apply where condition to filter the records:
var searchText = "A";
return (from a in _context.Names
select new Dto
{
Name = a.Name
})
.Where(x=>x.Name.ToLower().Contains(searchText.ToLower()))
.AsEnumerable()
.GroupBy(x => new { x.Name })
.Select(x => new Dto
{
Name = x.Key.Name
})
.AsQueryable();

Optimized Linq IEnumerable query

I have a query which is enumerating over and over and taking very long to run. Can somebody help me optimized it.
public EmpListItem(IEnumerable<EmployeeTable> Emps)
{
IEnumerable<EmployeeTable> emptable = Emps as EmployeeTable[] ?? Emps.ToArray();
TeamList = emptable.Select(x => x.Surname
.Select(c => new EmployeeListItem(c.EmployeeTables.Where(emptable.Contains)))
.Where(x => x.EmpDtos.Any())
.ToList();
}

Query not projecting for oderby?

How can I add an orderby after the select?
//what I have now
string country_list = string.Join(":", ctx.Countries.Select(a => a.CountryName).ToArray());
return country_list;
//what I want to do, but the orderby doesnt see the projections
string country_list = string.Join(":", ctx.Countries.Select(a => a.CountryName).OrderBy(b => b.StateId).ToArray());
return country_list;
its the projection with b that isnt working
You have to call OrderBy before Select, because after projection the column you're trying to order by is no longer available:
string country_list = string.Join(":", ctx.Countries.OrderBy(b => b.StateId).Select(a => a.CountryName).ToArray());
ctx.Countries.Select(a => new { a.CountryName, a.StateId })
.OrderBy(b => b.StateId)
.ToArray()

Entity - how to get only one column

Is there any possibility to get only one column from .Where statement? For example - ID.
List<testB> test = db.testB.Where(x => x.UserID == userId).ToList();
Here I get all entites testB.
And I just want to return List<int> with testB.ID instead of List<testB>. How can I do this?
db.testB.Where(x => x.UserID == userId).Select(x => x.ID).ToList();
should return a List<int>
Try using .select like this
var test = db.testB.Where(x => x.UserID == userId)
.Select(a => new {
column = a.column
}).ToList();
this creates an anonymous type class of only on attribute. Try it out.

How to dynamically group a list depending on role in asp.net mvc

Here is my scenario: We would like to have a page listing donors, depending on the user viewing the page we would like to group by the donor's giving level, or just their sort name. The twist that is throwing me is that we would like to group the Anonomous Donors and give a count based on the grouping.
In my controller I have
[HttpGet]
public ActionResult Society(string id)
{
var society = _db.ONLINEDR_DONOR_LIST
.Include("ONLINEDR_DONORS")
.Single(s => s.DONOR_LIST_ID == id);
var donors = _db.ONLINEDR_DONORS
.Where(d => d.DONOR_LIST_ID == id)
.OrderBy(d => d.SUBGROUP_SORT)
.ThenBy(d => d.SORT_NAME)
.ToList();
if (User.Identity.Name == "public")
{
//First off, check to make sure the list is viewable.
if (society.PUBLIC_IND == "N")
RedirectToAction("Index", "Home");
donors = _db.ONLINEDR_DONORS
.Where(d => d.DONOR_LIST_ID == id)
.OrderBy(d => d.SORT_NAME)
.ToList();
}
var viewModel = new SocietyDetailViewModel()
{
Society = society,
Donors = donors
};
return View(viewModel);
}
I would like to have something like
donors = _db.ONLINEDR_DONORS
.Where(d => d.DONOR_LIST_ID == id)
.GroupBy(d => d.SORT_NAME)
.ToList();
Which I can pass to my view, and then somehow show in the view
<% if (Model.donor.GroupedByItemCount > 1) { %>
<%: Model.donor.GroupedByItemCount %>
<% } %
(I am still new to asp.net MVC and LINQ so any helpful references to explain what I am doing wrong would be appreciated as well).
Thanks so much.
In the declaration of the donors variable, the compiler can determine the type of donors to be List<Donor>
In the assignment within the desired code, donors must be a List<IGrouping<string, Donor>>
donors cannot simultaneously be both types.
Suppose you have this query:
List<IGrouping<string, Donor>> donors = _db.ONLINEDR_DONORS
.Where(d => d.DONOR_LIST_ID == id)
.GroupBy(d => d.SORT_NAME)
.ToList();
This query is local and gives you the keys:
donors.Select(g => g.Key)
This query is mixed mode. A query is sent to the database for each item in the list to fetch its count. This is a potential performance problem.
donors.Select(g => g.Count())
This behavior is due to the difference between LinqToObjects groupby and sql's groupby.
In sql's groupby, you get the key and the aggregates - no elemeents.
In LinqToObjects, you get the key and the elements of the group - and can compute the aggregates from the elements.
Suppose you have this query:
List<IGrouping<string, Donor>> donors = _db.ONLINEDR_DONORS
.Where(d => d.DONOR_LIST_ID == id)
.ToList()
.GroupBy(d => d.SORT_NAME)
.ToList();
In the above query, the records are first hydrated, and then grouped locally. All queries on the result are local.
This query shapes the result data from IGrouping<string, Donor> to GroupShape. GroupShape is some class you make up that has SortName and Count properties.
donors.Select(g => new GroupShape()
{
SortName = g.Key,
Count = g.Count()
});
Suppose you have this query:
List<GroupShape> donors = _db.ONLINEDR_DONORS
.Where(d => d.DONOR_LIST_ID == id)
.GroupBy(d => d.SORT_NAME)
.Select(g => new {SortName = g.Key, Count = g.Count()})
.ToList()
.Select(x => new GroupShape()
{
SortName = x.SortName,
Count = x.Count
}).ToList();
Here, the grouping and counting are done in the database. Each row is first hydrated into an anonymous instance and then copied into an instance of GroupShape (a class you make up).

Resources