ravendb query return different result for count method and tolist().count
query 1(return 9):
var count = session.Query<MobileForm,ByFormNameIndex>().Where(x => x.RequestType == RequestType.Db && x.BelongTo == oaname).ToList().Count;
query 2(return 44):
var count = session.Query<MobileForm,ByFormNameIndex>().Where(x => x.RequestType == RequestType.Db && x.BelongTo == oaname).Count();
index define:
public class ByFormNameIndex : AbstractIndexCreationTask<MobileForm>
{
public ByFormNameIndex()
{
Map = mobileForms => from form in mobileForms
select new
{
form.FormName,
form.BelongTo,
form.RequestType,
form.CreateTime,
form.Uuid
};
Analyzers.Add(x => x.FormName, "Lucene.Net.Analysis.PanGu.PanGuAnalyzer,PanGu.Lucene.Analyzer, Version=1.3.1.0, Culture=neutral, PublicKeyToken=null");
Indexes.Add(x => x.FormName, FieldIndexing.Analyzed);
Indexes.Add(x => x.BelongTo, FieldIndexing.NotAnalyzed);
Indexes.Add(x => x.RequestType, FieldIndexing.NotAnalyzed);
Indexes.Add(x => x.Uuid, FieldIndexing.NotAnalyzed);
}
}
query1 return the right count, so what's the differrent for this to method?show i new to rebuild the index to get the right result?
That is by design.
Count() will give you the total count.
ToList() gives you the first page only. And then you get the count on that.
Related
I'm implementing ASP.NET Core project and have a query like the following for finding count of distinct userId per operatorName, however it shows me error for the line count distinct after running the project:
var activeUserPerOperatorCount = requests.GroupBy(x => new { operatorName = x.Operator.Name, x.UserId }).Select(x => new
{
userIds = x.Key.UserId,
operatorNames = x.Key.operatorName,
activeUserPerOperatorCount = x.Select(l => l.UserId).Distinct().Count()
}).ToList();
I appreciate if anyone helps me how can I find distinct count of userId per operatorName in my query.
ok, the correct query is like the following and it works correctly:
var activeUserPerOperatorCount = requests.GroupBy(x => new { operatorName = x.Operator.Name}).Select(x => new
{
operatorNames = x.Key.operatorName,
activeUserPerOperatorCount = requests.Select(l => l.UserId).Distinct().Count()
}).ToList();
So I have my View setup like this in the controller:
public ActionResult View(Guid projectID)
{
OnboardModel model = context.onboard_projectInfos.Where(x => x.projectID == projectID).Select(x =>
new OnboardModel()
{
propertymanagername = x.propertymanagername,
propertymanagercontactemail = x.propertymanagercontactemail,
date_modified = (DateTime)x.date_modified,
projectmanagercontactnumber = x.projectmanagercontactnumber,
Developer = x.onboard_projectCreate.Developer,
status1 = x.onboard_projectCreate.status1,
ProjectName = x.onboard_projectCreate.ProjectName
}).SingleOrDefault();
var pix = projectID.ToString();
context.onboard_BuildingInfos.Where(x => x.buildprojectID == pix).GroupBy(x => x.buildprojectID).Select(g => {
model.totalres = g.Sum(b => b.numberofres);
model.totalcom = g.Sum(b => b.numberofcommer);
});
return View(model);
}
Problem is grabbing the sum of numberofres and numberofcommer from BuildingInfos.
Using .Select gives me the error:
Error CS0411 The type arguments for method 'Queryable.Select(IQueryable, Expression>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
How to I write this LINQ statement correctly?
Thanks.
You cannot modify an object within a select (you can only create a new object). Further, you can't add new properties to an existing object.
We'll assume that OnboardModel defines the totalres and totalcom properties.
var query = context.onboard_BuildingInfos
.Where(x => x.buildprojectID == pix)
.GroupBy(x => x.buildprojectID);
foreach(var g in query)
{
model.totalres = g.Sum(b => b.numberofres);
model.totalcom = g.Sum(b => b.numberofcommer);
}
I do have the following LINQ query, selecting movies from my database that either contain the given search string or have one or more of the tags that I give to the function.
The problem is, that if the search string or the tags parameter are empty/null, I get no movies. The desired action however, is to get all the movies, so, if one parameter is null or empty, I don't want to apply it.
How can I do that?
public IEnumerable<Group<Genre, Movie>> GetMoviesGrouped(string search, List<Tag> tags)
{
var movies = from movie in Movies
where ( movie.Name.Contains(search)) && movie.Tags.Any(mt => tags.Any(t => t.ID == mt.ID))
group movie by movie.genre into g
select new Group<Genre, Movie> { Key = g.Key, Values = g };
....
}
Just for readability, I like to do it step by step
var movies = Movies;
if (!string.IsNullOrEmpty(search))
movies = movies.Where(m => m.Name.Contains(search));
if (tags != null && tags.Any()) {
var tagIds = tags.Select(m => m.ID);
movies = movies.Where(m => m.Tags.Any(x => tagIds.Contains(x.ID));
}
var result = from movie in movies
group ...
You can do something like this to skip the check if nothing is provided:
where (string.IsNullOrEmpty(search) || movie.Name.Contains(search)) &&
(!tags.Any() || movie.Tags.Any(mt => tags.Any(t => t.ID == mt.ID)))
I have a database in Azure that I created from scratch (not using code first in EF) and made a column in one of my tables to represent an Enum from my C# classes.
The enum is
public enum ItemType
{
Build,
Stock,
Shell,
Parts,
[Display(Name="All Vehicles")]
AllTypesOfVehicles
}
I am trying to select certain records in an EF Linq Query by using this enum in the where clause. I simply cast the enum to its underlying int32 data type but it does not retrieve me the results I want.
var results = context.Items.Include(P => P.Manufacturer)
.Include(P => P.Category).Include(P => P.VehicleMake)
.Include(P => P.VehicleModel).Include(P => P.VehicleYear);
//Fetches specific type of item
if (TypeOfPart != StaticData.ItemType.AllTypesOfVehicles)
{
results.Where(P => P.Type == (int)TypeOfPart); //This does not work
}
else //fetches all vehicle types
{
results.Where(P => P.Type == 0 | P.Type == 1 | P.Type == 2);
}
Is this expected in EF? I know EF supports Enum from a code first approach but I don't see why this would cause a problem. I went into my Azure portal and wrote a manual query to see if I would get the results that I wanted and I did.
SELECT * FROM Items WHERE Type = 2
This yielded me only results that were of enum type "Shell". Even hardcoding the number 2 into the where clause in my EF query does not get me the results I want. I rechecked my code to make sure I wasn't overriding that where clause anywhere else and everything seems clean. Just to be sure I even called .ToList() right after the where clause but still got bad results.
I'm not quite sure what I'm missing here???
============Edit after first answer=======================
var results = context.Items.Include(P => P.Manufacturer)
.Include(P => P.Category).Include(P => P.VehicleMake)
.Include(P => P.VehicleModel).Include(P => P.VehicleYear);
//Fetches specific type of item
if (TypeOfPart != StaticData.ItemType.AllTypesOfVehicles)
{
var part = (int)TypeOfPart;
results.Where(P => P.Type == part);
List<Item> t = results.ToList();
}
else //fetches all vehicle types
{
results.Where(P => P.Type == 0 | P.Type == 1 | P.Type == 2);
}
You have to assign results.Where() back to results to get it work and try performing the cast outside EF query context:
//Fetches specific type of item
if (TypeOfPart != StaticData.ItemType.AllTypesOfVehicles)
{
var part = (int)TypeOfPart;
results = results.Where(P => P.Type == part ); //This does not work
}
else //fetches all vehicle types
{
results = results.Where(P => P.Type == 0 | P.Type == 1 | P.Type == 2);
}
And btw, should you just skip the P.Type related Where when you're trying to fetch all types of vehicles? It would mean you don't need else.
//Fetches specific type of item
if (TypeOfPart != StaticData.ItemType.AllTypesOfVehicles)
{
var part = (int)TypeOfPart;
results.Where(P => P.Type == part ); //This does not work
}
Below returns all of the people in a building and all of their computers, and this works.
I want to change this to only include the Computers where Active == 1 and only the ActivityLogs where ActivityTypeId == 5. But if they don’t have either I still want the person returned.
public IQueryable<Person> GetPeople(int BuildingId)
{
return this.ObjectContext.People
.Include("Computers")
.Include("ActivityLog")
.Where(p => p.buildingId == BuildingId && !p.migrated)
.OrderBy(p => p.name);
}
Unfortunately this is not possible using Include syntax. As an alternative, you can select each entity individually like so:
var queryWithAllData = this.ObjectContext
.People
.Select(p => new
{
Person = p,
Computers = p.Computers.Where(c => c.Active == 1),
ActivityLogs = p.ActivityLog.Where(a => a.ActivityTypeId == 5)
});
// Do what you need with the records now that you have all the data.