linq count error: DbExpressionBinding requires an input expression with a collection ResultType. Parameter name: input - linq

I'm trying to run the following linq query:
var entries = from entry in _db.Entries
select new CommentSummary()
{
NumberOfComments = entry.Message.Count(),
UserName = entry.Name
};
when I execute the query, it throws the mentioned error:
Message=DbExpressionBinding requires an input expression with a collection ResultType.
Parameter name: input
If I use
var entries = from entry in _db.Entries
group entry by entry.Name into groupedByName
orderby groupedByName.Count() descending
select new CommentSummary
{
NumberOfComments = groupedByName.Count(),
UserName = groupedByName.Key
};
there is no error, but the Comments are not counted correctly: all NumberOfComments values are "1", and there should be some "1" and some "0".
Any ideas? Thanks

you should use 'by new' after 'group'. I hope this will help you.
var entries = from entry in _db.Entries
group entry by new { entry.Name } into groupedByName
select new
{
groupedByName.Key.Name,
NumberOfComments = groupedByName.Count(x => x.Name != null)
};

Related

How to count distinct

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();

LINQ to Entities does not recognize the method 'Boolean HasFlag(System.Enum)' method, and this method cannot be translated into a store expression

I have this service:
//seroiunoiweucroewr
///wercewrwerwerwer
//wcererewrwerwer
public List<UserRoleContract> GetRolePagesByUserId(long plngUserId, DisplayType displayType)
{
List<UserRoleContract> result = new List<UserRoleContract>();
using (CitiCallEntities context = new CitiCallEntities())
{
try
{
//var DisplayList = Utility.GetEnumDescriptions(typeof(DisplayType)).ToList();
//var selectValue = DisplayList.Where(i => i.Key == (byte) DisplayType.Windows).FirstOrDefault();
result = (from oUser in context.User
join oUserRole in context.UserRole on oUser.Id equals oUserRole.UserId
join oRoleRightsPage in context.RoleRightsPage.Where(i => i.IsActive == true)
on oUserRole.RoleId equals oRoleRightsPage.RoleId
join oApplicationPage in context.ApplicationPage.Where(i => i.IsActive == true)
on oRoleRightsPage.PageId equals oApplicationPage.Id
join oRole in context.Role on oUserRole.RoleId equals oRole.Id
join oEmployee in context.Employee on oUser.EmployeeId equals oEmployee.Id
join oSection in context.Section on oEmployee.SectionId equals oSection.Id
where oUser.IsActive == true && oUser.Id == plngUserId
&& oRole.IsActive == true && (((DisplayType)oRoleRightsPage.DisplayType).HasFlag(displayType))
//am getting error in has flag
// am having three display type web, windows and all
// how to overcome
select new UserRoleContract
{
UserId = oUser.Id,
RoleId = oRole.Id,
RoleName = oRole.RoleName,
PageID = oApplicationPage.Id,
PageName = oApplicationPage.PageName,
IsOPsCtrl = oRole.IsOPsCtrl,
ISOPsCtrlFor = oRole.OPsCtrlFor,
SectionId = oSection.Id,
DisplayType = oRoleRightsPage.DisplayType,
}).Distinct().ToList();
}
catch (Exception exception)
{
HandleExpcetion(exception);
//throw new CitiCallException(exception.Message);
}
}
return result;
}
I am getting Linq error in has flag conversion, how do I overcome this problem?
you are geeting error because HasFlag method is not paresent in database i.e. it might be part of language or local function in code which is not present in database.
So when query is translated it found this method is not available and that is the reason you are getting error.
one solution to avoid this error is
Brind all data from databae
Than filter than data, i.e. apply HasFlag method of it.
But this will bring all data and might decrease performance.
Example is
remove this line (((DisplayType)oRoleRightsPage.DisplayType).HasFlag(displayType) from your query
var list = querieddata //first fetch data without hasflag condition/method
.AsEnumerable() // Rest of the query in-process
.Where(oRoleRightsPage=> ((DisplayType)oRoleRightsPage.DisplayType).HasFlag(displayType))//apply condition here once fetching done
.ToList();
The HasFlag method has no equivalent in Linq to Entities which is why you get that error. You can get around it by using bitwise comparison instead of using HasFlag, for example this:
((DisplayType)oRoleRightsPage.DisplayType).HasFlag(displayType)
Becomes:
(oRoleRightsPage.DisplayType & displayType) > 0

EF and LINK query not giving all table values in "select"

How do I use a column in the "where" that I haven't inluded in the "select"? The "where" method isn't showing me all the columns in my SQL Server table, only the 3 in the select statement. I need to do the select based on a different column in the table:
using (var context = new URIntakeEntities())
{
return context.Claims.Select(
u => new Models.Claim
{
ClaimNumber = u.ClaimNumber,
DateOfInjury = u.DateOfInjury,
Denied = u.Denied
}).Where(u => u.?????).ToList();
}
You should move your where statement before the select statement.
using (var context = new URIntakeEntities())
{
return context.Claims.Where(u=> u.?????).Select(
u => new Models.Claim
{
ClaimNumber = u.ClaimNumber,
DateOfInjury = u.DateOfInjury,
Denied = u.Denied
}).ToList();
}
How do I use a column in the "where" that I haven't included in the
"select"?
You can't. Where is applied on a current type of sequence. So, you should apply filter before projecting result:
using (var context = new URIntakeEntities())
{
return context.Claims
.Where(u => u.?????)
.Select(u => new Models.Claim
{
ClaimNumber = u.ClaimNumber,
DateOfInjury = u.DateOfInjury,
Denied = u.Denied
}).ToList();
}

Filter SelectListItem value using some condition

I have one SelectListItem for DropDownList. I have to filter based on some condition. If I try adding the condition then its gives me an error like this (LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression). I ll be adding that code here. Please guide me to solve this.
Code
IEnumerable<SelectListItem> IssueId = (from txt in Db.Issues where txt.BibId == BibId
select new SelectListItem()
{
Text = txt.Description,
Value = txt.Id.ToString(),
Selected = true,
});
SelectList IssueIds = new SelectList(IssueId, "Value", "Text");
ViewBag.IssueId = IssueIds;
Thanks
Try this:
LINQ2EF does not know ToString() but after AsEnumerable() you'll get a local collection when ToString() is implemented.
IEnumerable<SelectListItem> IssueId =
(from txt in Db.Issues.Where(e => e.BibId == BibId).AsEnumerable()
select new SelectListItem()
{
Text = txt.Description,
Value = txt.Id.ToString(),
Selected = true
});
Linq To Sql can't generate TSQL for txt.Id.ToString()
You will need to iterate the result instead after executing the query, or cast to Enumerable as xeondev suggests.
That extension does not seem to be sorted by linq to Entities but you could just do the mapping once you have the issues, e.g.
var issues = (from issue in Db.Issues
where issue .BibId == BibId
select issue ).ToList();
IEnumerable<SelectListItem> IssueId = (from txt in issues
where txt.BibId == BibId
select new SelectListItem()
{
Text = txt.Description,
Value = txt.Id.ToString(),
Selected = true,
});

Only primitive types ('such as Int32, String, and Guid') are supported in this context when I try updating my viewmodel

I am having some trouble with a linq query I am trying to write.
I am trying to use the repository pattern without to much luck. Basically I have a list of transactions and a 2nd list which contains the description field that maps against a field in my case StoreItemID
public static IList<TransactionViewModel> All()
{
var result = (IList<TransactionViewModel>)HttpContext.Current.Session["Transactions"];
if (result == null)
{
var rewardTypes = BusinessItemRepository.GetItemTypes(StoreID);
HttpContext.Current.Session["Transactions"] =
result =
(from item in new MyEntities().TransactionEntries
select new TransactionViewModel()
{
ItemDescription = itemTypes.FirstOrDefault(r=>r.StoreItemID==item.StoreItemID).ItemDescription,
TransactionDate = item.PurchaseDate.Value,
TransactionAmount = item.TransactionAmount.Value,
}).ToList();
}
return result;
}
public static List<BusinessItemViewModel>GetItemTypes(int storeID)
{
var result = (List<BusinessItemViewModel>)HttpContext.Current.Session["ItemTypes"];
if (result == null)
{
HttpContext.Current.Session["ItemTypes"] = result =
(from items in new MyEntities().StoreItems
where items.IsDeleted == false && items.StoreID == storeID
select new BusinessItemViewModel()
{
ItemDescription = items.Description,
StoreID = items.StoreID,
StoreItemID = items.StoreItemID
}).ToList();
}
return result;
However I get this error
Unable to create a constant value of type 'MyMVC.ViewModels.BusinessItemViewModel'. Only primitive types ('such as Int32, String, and Guid') are supported in this context.
I know its this line of code as if I comment it out it works ok
ItemDescription = itemTypes.FirstOrDefault(r=>r.StoreItemID==item.StoreItemID).ItemDescription,
How can I map ItemDescription against my list of itemTypes?
Any help would be great :)
This line has a problem:
ItemDescription = itemTypes.FirstOrDefault(r=>r.StoreItemID==item.StoreItemID)
.ItemDescription,
Since you are using FirstOrDefault you will get null as default value for a reference type if there is no item that satifies the condition, then you'd get an exception when trying to access ItemDescription - either use First() if there always will be at least one match or check and define a default property value for ItemDescription to use if there is none:
ItemDescription = itemTypes.Any(r=>r.StoreItemID==item.StoreItemID)
? itemTypes.First(r=>r.StoreItemID==item.StoreItemID)
.ItemDescription
: "My Default",
If itemTypes is IEnumerable then it can't be used in your query (which is what the error message is telling you), because the query provider doesn't know what to do with it. So assuming the that itemTypes is based on a table in the same db as TransactionEntities, then you can use a join to achieve the same goal:
using (var entities = new MyEntities())
{
HttpContext.Current.Session["Transactions"] = result =
(from item in new entities.TransactionEntries
join itemType in entities.ItemTypes on item.StoreItemID equals itemType.StoreItemID
select new TransactionViewModel()
{
ItemDescription = itemType.ItemDescription,
TransactionDate = item.PurchaseDate.Value,
TransactionAmount = item.TransactionAmount.Value,
CustomerName = rewards.CardID//TODO: Get customer name
}).ToList();
}
I don't know the structure of your database, but hopefully you get the idea.
I had this error due a nullable integer in my LINQ query.
Adding a check within my query it solved my problem.
query with problem:
var x = entities.MyObjects.FirstOrDefault(s => s.Obj_Id.Equals(y.OBJ_ID));
query with problem solved:
var x = entities.MyObjects.FirstOrDefault(s => s.Obj_Id.HasValue && s.Obj_Id.Value.Equals(y.OBJ_ID));

Resources