Divide in a Linq to SQL query - asp.net

How can I form a Linq to sql Query for this code in SQL, I tried several things. This is my basic code:
List<Movie> movies =
(from item in db.Movies select item).ToList<Movie>();
return movies;
This is what I want as a result.
select (Won/Total) as 'rankPercentage'
from dbo.Filmranking
order by rankPercentage desc
Thanks

var movies =
(from items in db.Movies
select new { RankPercentage = item.Won / item.Total })
.ToList();
At this point, movies will be a List<T> where T is a float or int depending on the underlying SQL type (which I cannot discern from your question). If you really want to project this back as a List<Movie>, you will need to project that as follows but your result is not likely to match your SQL table.
List<OtherMovieType> movies =
(from items in db.Movies
select new OtherMovieType() {
Name = item.Name,
RankPercentage = item.Won / item.Total
})
.ToList();

item.Won / db.Awards.Count
Is count a property? I think it is.

You need something called projection, something like this:
var result = db.Movies
.Select(x => new { title=x.Title, rank = (x.Won/x.Total) })
.OrderBy(x => x.rank);
EDIT Maybe you want the title to identify your records :)

Related

Multiple request instead of one in EF Core

I have this select which I expected to be executed by sending one command to SQL Server but I can see 10s requests instead. How can I fix it?
We have Companies which have Customers and Orders. For some reasons Orders are under Company entity.
var q = _dbContext.Companies
.Include(x => x.Customers)
.Include(c => c.Orders)
.Where(a => a.CompanyId == 123);
var total = await q.CountAsync();
q = q.OrderByDescending(x => x.CompanyCode)
.Skip((pageIndex - 1) * pageSize).Take(pageSize);
var res = await q.Select(x => new ResultDto()
{
CompanyCode = x.CompanyCode,
Customers = x.Customers
.Where(c => c.IsActive)
.Select(c => new CustomerDto()
{
FirstName = c.FirstName,
Surname = c.Surname,
Orders = x.Orders
.Where(o => o.IsOpen)
.Select(o => new OrderDto()
{
DateCreated = o.DateCreated
}).ToList()
}).FirstOrDefault(),
}).ToListAsync();
This is EF.NetCore optimization.
You actually cant achieve one query when your navigation properties are collections.
I can't find any links right now, but this is by design.
Once you have a collection in your navigations inside select or inside includes it will produce a separate query for each root entity. The reason I believe is the redundant data amount produced by such a query.
I suggest leave it as is if you have not a lot of data < 1000 rows in a result. You will see a lot of queries but they will be really fast.
As I can see you have pagination here so it shouldn't be a problem.
Otherwise, select your collections separately and join them in memory carefully.
Unfortunately, there is no other way for EF Core
Also, I recommend to turn on EF core logs to what is going on early. I bet FirstOrDefault will produce some warning.

Linq Query Distinct Function do not work with DropdownList

I want to assign Linq Query result to dropdownlist which contain a
Distinct function
My Code:-
var area = de.City_Area_View
.Select(m => new { m.Area_Id, m.Area_Name})
.Distinct()
.ToList();
drpfilter.DataTextField = "Area_Name";
drpfilter.DataValueField = "Area_Id";
drpfilter.DataSource = area;
drpfilter.DataBind();
Problem :- When I write this code then I get Below Error
Error:- The method 'Distinct' is not supported.
I get System.NotSupportedException.
I want to assign a Distinct name of area to the DropDownList
So please help me for this problem.
If your set is small enough (so you don't mind fetching all the values from the database), the simplest thing would be to force the distinct part to be performed locally:
var area = de.City_Area_View
.Select(m => new { m.Area_Id, m.Area_Name})
.AsEnumerable()
.Distinct()
.ToList();
AsEnumerable simply "changes" the expression type to IEnumerable<T> instead of IQueryable<T>, so that the compiler calls Enumerable.Distinct instead of Queryable.Distinct - and Enumerable.Distict will definitely work.

ASP.net Entity Framework DropDownList Source Query not Returning Any Result

When I try the following SQL query, I get the result, I want:
SELECT City FROM Hotel GROUP BY City
But the following Entity Framework query does not returning any result:
string CityKey = CityDropDownList.SelectedValue;
MedicalEntities entity = new MedicalEntities();
CityDropDownList.DataSource = (from p in entity.Hotels
where p.City == CityKey
group p by p.City into g
select new
{
City = g.Key
}).ToList();
I have tried so many variations of that query but no go.
I guess, its pretty straight forward and no extra information is needed. Any help would be appreciated
I don't know why you think you need to use the Group by..
CityDropDownList.DataSource = entity.Hotels.Select(x => new { City = x.City })
.Distinct().ToList();

Correctly structuring this LinqToSql code

Normally I use stored procedures / work in SQL so apologies if I get the terminology slightly off here..
I have a database, with 3 seperate tables, and I need to search multiple fields in each of the 3 tables.
Im sure that I am not doing this the mose effective way, initially I am trying to do it in simple seteps to understand it.
I have the following;
var foo1 = entities.table1.Where(a => a.bodyText.Contains(searchString) || a.pageTitle.Contains(searchString));
var foo2 = entities.table2.Where(b => b.newsArticle.Contains(searchString) || b.newsArticle.Contains(searchString));
var foo3 = entities.table3.Where(c => c.ImageDescriptionContains(searchString));
I need to combine all these results into a single repeater for display.
At this point all 3 sets of data are in seperate, unique collections of anonymous data. So whats the best way of converting these into a single coherent bindable source?
I was thinking of itereating through each list in turn, pulling out the fields I need to display and putting them in a new class, then binding a lsit of these classes to the repeater.
But it all seems a bit clunky to me.
Is there a way of doing the search across all 3 tables in one go, and returning just the fields I need from each table, with a common name (i.e. in SQL I could write
select b.newsArticle as myText,
or
select newsArticle, ''
to return the news article and an empty string).
This would combine:
var foos = foo1.ToList();
foos.AddRange(foo2);
foos.AddRange(foo3);
To get just what you want:
var myExtractedValues = foos.Select(x => new {
Article = !string.IsNullOrEmpty(x.newsArticle))
? x.newsArticle
: string.Empty});
I have used an anonymous type here but you could swap the new {} with a type of your own.
I reverse the operator on the IsNullOrEmpty but that is just a personal preference (I prefer how is reads.)
To get all the results in one go you'll need to define a common class that will be used by all three queries to store the result. This class may be as well anonymous but I'll name it just for clarity.
class Data
{
public string Text{ get; set;}
}
Now, in your code you'll fetch instances of Data from database and you can use Union:
using( var entities = new YourDataContext)
{
var foo1 = entities.table1
.Where(a => a.bodyText.Contains(searchString) ||
a.pageTitle.Contains(searchString))
.Select(a => new Data{ Text = a.bodyText});
var foo2 = entities.table2
.Where(b => b.newsArticle.Contains(searchString) ||
b.newsArticle.Contains(searchString))
.Select(b => new Data{ Text = b.newsArticle});
var foo3 = entities.table3
.Where(c => c.ImageDescription.Contains(searchString))
.Select(c => new Data{ Text = c.ImageDescription});
return foo1.Union(foo2).Union(foo3);
}

LINQ: How to rewrite the WHERE clause in query?

My simple one keyword query works as follows:
var query = from product in dc.catalog
where product.Name.Contains("table")
select product;
I want to provide more flexibility in the query and get keywords from a textbox which can come from a string like "table red round". Here I want the result to have the records that contains ALL of the 3 words (red, round, table) IN ANY ORDER.
How do I rewrite the WHERE clause to handle this? Thanks.
var a = from product in dc.catalog
where textbox1.Text.Split(' ').All(nam => product.Name.Contains(nam))
select product;
How about this (just noticed you want all):
var query = from product in dc.catalog
where textBox.Text.Split(' ').All(s => product.Name.Contains(s))
select product;
// You can produce these matches using any method (string.Split, e.g.)
// Just make sure that they're an array or a list.
var matches = new[]{"table", "red", "round"};
var query = from product in dc.catalog
where matches.All(m => product.Name.Contains(m))
select product;
Look at the Except function
e.g.
var query = from product in dc.catalog
where !selectedItems.Except(product.Name).Any()
select product;

Resources