Retrieve the item from the list - c#

I am trying to get the list of Courses from the courseData list item.
However, the following returns me boolean.
var course = courseData.Courses.Select(x => x.Entities.Select(a => a.courseId == courseDto.Id)).FirstOrDefault();

Currently, course is of type IEnumerable<bool> because in your inner Select clause you're projecting from some type a and returning a.courseId == courseDto.Id (bool) which results in an IEnumerable<bool> after the provided lambda is executed for each element of x.Entities.
Once the execution of the outer Select clause is performed this then results in having a type IEnumerable<IEnumerable<bool>> which when you then call FirstOrDefault() upon; simply results in retrieving the first IEnumerable<bool> element.
Now, you're most likely looking for the Where clause so that you can retain all the elements that pass the predicate a => a.courseId == courseDto.Id. We will then flatten the IEnumerable<IEnumerable<Entity>> into IEnumerable<Entity> and then collect to a list or retrieve the first element if exists else the default for reference types (null).
To retrieve a list of courses.
var course =
courseData.Courses
.SelectMany(x => x.Entities.Where(a => a.courseId == courseDto.Id))
.ToList();
To retrieve the first item from the list of courses.
var course =
courseData.Courses
.SelectMany(x => x.Entities.Where(a => a.courseId == courseDto.Id))
.FirstOrDefault();

var Result = Course_Object.Where(u => u.Id == 1).FirstOrDefault();

Related

I can not make the correct linq request

I form a request, it works.
var query = db.Persons.Where(p => p.Date == "27.02.2020").Where(p => p.Country == "USA");
But since I will need to use it in if-else
I changed it a little and now he just selects the last Where.
How can this problem be solved?
var query = db.Persons;
query.Where(p => p.Date == "27.02.2020");
query.Where(p => p.Country == "USA");
The Where method, like all LINQ methods, does not modify the source enumerable in-place, but instead returns a new enumerable that has the operation, or in this case filter, applied to it.
That means you need to assign the result of each operation back into your variable for it to persist. The following should be equivalent to your original snippet:
IQueryable<Person> query = db.Persons;
query = query.Where(p => p.Date == "27.02.2020");
query = query.Where(p => p.Country == "USA");
As pointed out in the comments, the query variable type now needs to be compatible with both the type of db.Persons and the return type of Where.

How to get value from Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable in mvc controller

I know the title is somewhat complicate but let I clear the title by explaining the problem.
As per image I want to filter product name in search textbox. For ex: In search textbox if I enter the oil that in datatable whole data want to show which product name is oil.
For filter I used linq query, here is my code,
var dataList = (from x in query
select new
{
PartName = _Db.Part.Where(z => z.Id == x.Select(p => p.PartId).FirstOrDefault()).Select(p => p.Name),
ManufacturerName = _Db.Manufacture.Where(z => z.Id == x.Select(p => p.ManufacturerId).FirstOrDefault()).Select(p => p.name),
CategoryName = _Db.Category.Where(z => z.Id == x.Select(p => p.CategoryId).FirstOrDefault()).Select(p => p.Name),
Pcs = x.Sum(o =>o.Pcs) -
(from m in _Db.MaterialRecord
join s in _Db.ServiceJob on m.ServiceJobId equals s.Id
where m.pid == x.Select(p => p.PartId).FirstOrDefault()
select m).Sum(z => z.Qty),
Weight = _Db.Purchase.Where(p => p.Weight == x.Select(s => s.Weight).FirstOrDefault()).Select(a => a.Weight).FirstOrDefault(),
WeightType = x.Select(p => p.WeightTypeId).FirstOrDefault() > 0 ?((WeightType)x.Select(p => p.WeightTypeId).FirstOrDefault()).ToString() :"",
}).ToList();
//Search
if (!string.IsNullOrEmpty(searchValue))
dataList = dataList.Where(m => m.CategoryName.Contains(searchValue.ToString().ToLower())).ToList();
//Returning Json Data
return Json(new { draw = draw, recordsFiltered = recordsTotal, recordsTotal = recordsTotal, data = data });
As per code I am getting whole data in datalist variable. Now, when I search any product in searchbox at that time the condition of search will true and after that the datalist value will be null[as shown by debug the code].
So, hence from that datatable shows null data.
For understanding that why this happening I add the tostring() in datalist query of category line i.e.
CategoryName = _Db.Category.Where(z => z.Id == x.Select(p => p.CategoryId).FirstOrDefault()).Select(p => p.Name).toString(),
After adding toString() in this line it shows this line Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable. But I want the result value of this line. For more clear lets see the another image
That oil result value I want in search condition line i.e.
dataList = dataList.Where(m => m.CategoryName.Contains(searchValue.ToString().ToLower())).ToList();
but right now in it is showing this line Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable in the place of result value.
First thing you should know is ToString() by its default implementation returns fully-qualified name of the object when applied to collection objects, in this case returns Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable<string> which is a reference type that doesn't override that method.
Let's evaluate this expression first:
CategoryName = _Db.Category.Where(z => z.Id == x.Select(p => p.CategoryId).FirstOrDefault())
.Select(p => p.Name),
Assumed that Category has DbSet<Category> type, the Select() extension method used in code above returns EntityQueryable<string> which contains result set collection from executed SQL statement provided by LINQ-to-Entities query. If you want to pull single string value from that collection, you must use one of the First(), Single(), FirstOrDefault() or SingleOrDefault() extension methods.
Hence, you should add extension method as mentioned above to return a string value instead of a collection:
var dataList = (from x in query
select new {
// other properties
CategoryName = _Db.Category.Where(z => z.Id == x.Select(p => p.CategoryId).FirstOrDefault())
.Select(p => p.Name).SingleOrDefault(),
// other properties
}).ToList();
Then you can use Contains against a substring (searchValue) because CategoryName has string type:
dataList = dataList.Where(m => m.CategoryName.Contains(searchValue.ToString().ToLower())).ToList();
Reference:
Entity Framework/Core and LINQ to Entities Query Methods (Operators)

dynamic filters in asp.net mvc 4

I want to do something like this:
var list = db.Respaldoes.Where(x => x.type == "Backup");
if (condicion1)
list.Where(x => x.entity == "GIELCJLT03");
if (condicion2)
list.Where(x => x.activity_type == "0");
I don't know if something like this is possible, I get the list but the filters are never applied.
You could try something like this:
var list = db.Respaldoes.Where(x => x.type == "Backup");
if (condicion1)
list = list.Where(x => x.entity == "GIELCJLT03");
if (condicion2)
list = list.Where(x => x.activity_type == "0");
Initially the list when the Where clause, x => x.type == "Backup", will be executed it will give you the initial list you refer to. Then, if the condicion1 is true, you will make a second fitering and you will assign the result to list. There again you have deffered execution. Only when list will be requested to be consumed by another piece of your code will be executed -hence the name deffered execution. The same holds for the second condicion and so on.
Where returns an IEnumerable<T>, which defers the execution until a later action forces the query to be resolved. If you want to resolve your query, immediately execute it with ToList().
In addition, you are not actually doing anything with your filtered list. By reassigning the filtered list to your original list object, it will update the collection with the filter, removing objects that do not match your predicate.
var list = db.Respaldoes.Where(x => x.type == "Backup");
if (condicion1)
list = list.Where(x => x.entity == "GIELCJLT03").ToList();
if (condicion2)
list = list.Where(x => x.activity_type == "0").ToList();

Default value for linq select item if query didn't return anything

How to insert a default value to the returned collection if the where condition returns no results?
from i in data.collection
where i.Type == type
select i.Count
Use the Enumerable.DefaultIfEmpty method to do this.
Example (in method syntax because it IMHO is less awkward):
data.collection.Where(i => i.Type == type)
.DefaultIfEmpty(defaultObject)
.Select(i => i.Count);
There's DefaultIfEmpty() method.
In the method syntax, you can use it like this:
data.Collection
.Where(i => i.Type == type)
.DefaultIfEmpty(yourDefaultValue)
.Select(i => i.Count);
If the Where filter returns no items, a one-item enumerable with yourDefaultValue is used as an input for the Select projection.
You're looking for DefaultIfEmpty.
var itemCounts = from i in data.collection
where i.Type == type
select i.Count;
var itemCountsOrMinusOne = itemCounts.DefaultIfEmpty(-1);
The first will give you the item counts, or an IEnumerable that returns no elements.
The second will then give you the item counts, or an IEnuemrable that just returns -1.

Converting an IEnumerable list to a grouped list in Linq

I have a function that returns the following type:
IEnumerable<IGrouping<String, ExportTransaction>>
In this function I create a list of the following type, using a linq expression:
IEnumerable<ExportTransaction>
The Linq code looks like this:
IEnumerable<ExportTransaction> transactions = ctx.ExportTransactions
.Where(x => x.Id != null);
How can I convert “transactions” to a grouped list of the type shown at the top of this page. The function does various things with the “transactions” so It must stay as “IEnumerable” inside the function but must be converted to the grouped list when returned.
I'll assume that the Transactions have a name property and that's what you want to group the Transactions by. If that's not the case, all you have to do is change the property in the GroupBy call:
var transactions = ctx.ExportTranactions
.Where(x => x.Id != null)
.GroupBy(x => x.Name);
Does it really need to be grouped and if so what do you want to group it by? It sounds to me like you have your data set and you could be trying to force it into a format you don't necessarily need.
Typically to group a data set you'd do something like:
var grouping = ctx.ExportTransactions.Where(x => x.Id != null)
.GroupBy(x => x.Description);
That would create an IEnumerable<IGrouping<string, ExportTransaction>> grouping all the transactions with an identical description, presuming that each transaction had description.
If you need all the records in a single group you can always do the following:
var grouping = ctx.ExportTransactions.Where(x => x.Id != null)
.GroupBy(x => string.Empty);
Which will give you what you need with the group key being an empty string, but I'd strongly advise against it and instead suggest looking at why you need to return a grouping when you don't seem to want to group by anything.

Categories

Resources