I've tried to do this (load some data from a db to send it by JSON)
But I've catched an excpetion:
Additional information: LINQ to Entities does not recognize the method
'Model.Models.User GetUserById(Int32)' method, and this method cannot
be translated into a store expression
How can I avoid this exception and get the userId which I needed for the each record
Entity Framework tries to convert your query into SQL query. But it fails to convert GetUserById method call into SQL (no surprise here). You should move this part of linq query to client side:
var favList = context.FavoriteMessages
.Where(m => m.UserId == user.UserId && m.OnlineRoomId == user.OnlineRoomId)
.Select(m => new {
m.UserId, // return user id from database
m.Instance,
m.CreatedOn
})
.AsEnumerable() // further part of query is not translated into SQL
.Select(i => new {
UserName = userService.GetUserById(i.UserId).Name, // get name locally
i.Instance,
i.CreatedOn
}).ToList();
But if you'll think about filtering part of your query, you'll see that you are selecting only messages which have userId equal to user.UserId. That means - all of selected messages will have same user id, and what is more important - that will be id of user which you already have. And even more - you already have name of user in User.Identity.Name. So, the query should look like:
var user = userService.GetUserByName(User.Identity.Name);
var favorites = from m in context.FavoriteMessages
where m.UserId == user.UserId && m.OnlineRoomId == user.OnlineRoomId
select new {
UserName = user.Name,
m.Instance,
m.CreatedOn
};
return Json(favorites.ToList(), JsonRequestBehavior.AllowGet);
Related
My Code:
elections = elections.Where(e => e.Creator == Username || e.Approver == Username || IsUserInCc(e.Cc,Username))
.OrderBy(e => e.Status)
.ThenByDescending(e => e.Group);
var test = elections.FirstOrDefault();
private bool IsUserInCc(string cc, string username)
{
var ccList = cc.Split(';');
if (ccList.Contains(username))
return true;
return LDAPUtility.Instance.IsUserInGroup(ccList.ToList(), username);
}
Error:
LINQ to Entities does not recognize method IsUserInCc.
From many posts, I can understand why error was thrown. Basically IsUserInCc is not available in SQL execution. I need somehow convert it back to C# to handle it.
LINQ to Entities does not recognize my method
LINQ to Entities does not recognize the method in query
LINQ to Entities does not recognize the method 'System.String ToString(Int32)'
However, in my specific case, what is the best approach?
You need to convert to list first. Also note that elections must be able to hold a list for this to run.
elections = elections.ToList().Where(e => e.Creator == Username || e.Approver == Username || IsUserInCc(e.Cc,Username))
.OrderBy(e => e.Status)
.ThenByDescending(e => e.Group);
For your function written in code, you cannot use that on Queryables. You need to convert to in-memory list and then apply the filter required using your function.
The root cause of your issue is that your underlying data isn't normalised properly. You need to put your CC's in a collection, not have them as a single deliniated string.
In SQL you'd need to add a new table called CC or something and put each user name in there and link it back to an election. Or if it's an in-memory collection, add a new property that in its Getter will do the split for you.
Either way, then you won't run into this kind of problem. If your data isn't properly structured, you will create problems for yourself further up the stack.
When you want to send request to databaseusing Linq like:
var query = listData.Where(x=>x.Id == 123);
Type of this query is IQueryable that means your query not Executed yet!
Now you are sending data as IQueryable to method and can not process on your data, you have to Execute that with methods like: Tolist(), ToListAsync() or something like these.
The best way for these is that you get data from database without that method, after that you execute your query, you can Run this method.
GoodLuck.
Can you try like this :
elections = elections.Where(e => e.Creator == Username || e.Approver == Username).Tolist().Where(e => IsUserInCc(e.Cc,Username))
.OrderBy(e => e.Status)
.ThenByDescending(e => e.Group);
var test = elections.FirstOrDefault();
private bool IsUserInCc(string cc, string username)
{
var ccList = cc.Split(';');
if (ccList.Contains(username))
return true;
return LDAPUtility.Instance.IsUserInGroup(ccList.ToList(), username);
}
I am currently trying to limit which users can access which groups, and am doing this by using linq. My problem occours when I am adding the relevant groups to the view.
The error I keep getting is:
LINQ to Entities does not recognize the method 'System.String
GetUserId(System.Security.Principal.IIdentity)' method, and this
method cannot be translated into a store expression
This is my code:
var groupUser = db.GroupUsers.Where(u => u.ApplicationUserId == User.Identity.GetUserId()).Select(gr => gr.GroupId);
pv.GroupList = db.Groups.Where(g => groupUser.Contains(g.Id)).ToList();
return View(pv);
You need to call GetUserId() outside the lambda expression, as Linq to Entities is not able to translate it to corresponding SQL (of course there is no SQL alternative for GetUserId()):
var userId = User.Identity.GetUserId();
var groupUser = db.GroupUsers.Where(u => u.ApplicationUserId == userId)
.Select(gr => gr.GroupId);
How to get Session["UserId"] value in Linq Query
var result = (from c in db.UserMaster
where c.UserID == Session["vUSerID"].ToString()
select C ).ToList();
but when i execute it gives me error as follows
LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression.
Please guide me how to works with ToString()
You need to materialize the value before you send it off to be translated to SQL:
var userId = Session["vUSerID"].ToString();
var result = (from c in db.UserMaster
where c.UserID == userId
select C ).ToList();
Alternatively, you could try bringing entity into memory first, and then apply the condition to get the filtered result, although not recommended because of the potential performance issue.
var result = db.UserMaster.Select(x => x).ToList().Where(x => x.UserId == Session["vUSerID"].ToString()).ToList();
Am I doing it wrong ir it is not possible to project a certain data model to strongly typed model instead of anonymous object?
I have this Linq expression:
var kudosLogsQuery = _kudosLogsDbSet
.Include(log => log.Type)
.Include(log => log.Employee)
.Where(log =>
log.OrganizationId == options.OrganizationId &&
log.BasketId == null)
.Where(StatusFilter(options.Status))
.Where(TypeFilter(options.TypeId))
.Where(UserFilter(options.SearchUserId))
.Select(log => new Comment
{
Id = log.Id,
Created = log.Created,
Employee = new Employee
{
FirstName = log.Employee.Name
}
Type = new Type
{
Name = log.Type.Name
}
})
.OrderByDescending(log => log.Created)
.ToList()
TypeFilter, StatusFilter, UserFilter is either x => true or just an another filter by Status, Type or User.
Unfortunately it produces an SQL statement that takes all fields from that table and projects it on the application side. The conclusion was made by testing these Linq expressions on SQL profiler.
Question:
Am I doing something wrong, or SQL projection works with anonymous objects only?
Thanks
I'm new in ASP.NET MVC 5, I need get the Icollection property and search into other property, if printed the result of the first search is fine, but when i go to search in the result is null.
what is the problem?
var userId = User.Identity.GetUserId();
var user = db.Users.Include( u=> u.Sucursales)
.Where(u => u.Id == userId)
.SingleOrDefault();
if( user != null )
{
var sucursal = user.Sucursales.Include(s => s.Emisor)
.Where(s => s.ID == suc)
.SingleOrDefault();
if (sucursal != null)
{
var tipoCfe = sucursal.Emisor.TiposCfe
.Where(t => t.ID == factura)
.SingleOrDefault();
Your query will take place right away since you are using SingleOrDefault(), see this StackOverflow question pertaining to SingleOrDefault() Your Include(s => s.Emisor) sticks out to me though. Since Emisor wasn't included when fetching the user, you will not be able to request that since your query is no longer of type IQueryable. Your query has already been executed.
In order to retrieve the data you require, you will have to obtain the data during your first query. I would do something similar to: db.Users.Include("Sucursales.Emisor") when you retrieve the user.
More on include method... MSDN Explanation of Include Method
I changed
var user = db.Users.Include( u=> u.Sucursales)
for
var user = db.Users.Include("Sucursales.Emisor")