how to use session variable in Linq - c#

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

Related

ASP.NET Entity Framework .Where() with Lesser than

How can I make this lesser than or equal work in my .Where() clause? I am getting an error.
var filteredProducts = Products.Where(p => p.State.Contains("Bruikbaar"))
.Where(p => p.Privilege <= ui.GetPrivilegeNumber())
.ToList();
Error:
LINQ to Entities does not recognize the method 'Int32 GetPrivilegeNumber()' method, and this method cannot be translated into a store expression.
I hope this question is never asked before. Googled couldn't find it either or I am using the wrong words to express my problem.
ui.GetPrivilegeNumber() is not a recognized method.
Use this:
var uiPrivilege = ui.GetPrivilegeNumber();
var filteredProducts = Products.Where(p => p.State.Contains("Bruikbaar"))
.Where(p => p.Privilege <= uiPrivilege)
.ToList();
And as other users mentionted, you can optimize your Where.
EF does not execute method calls which you use in predicates. It stores them as expression (i.e. syntax tree) and then analyzes this tree to build SQL query by translating C# code to SQL code. It cannot translate GetPrivilegeNumber() method call into SQL, because there is no appropriate SQL code for that. So all you need is move this method call out of expression and pass only result of method call instead:
var privilegeNumber = ui.GetPrivilegeNumber();
var filteredProducts = Products.Where(p => p.State.Contains("Bruikbaar"))
.Where(p => p.Privilege <= privilegeNumber)
.ToList();
Now privilegeNumber is just an integer variable which is translated into SQL parameter
SELECT * FROM Products p
WHERE p.State LIKE '%Bruikbaar%' AND p.Privilege <= #privilegeNumber
You need to move ui.GetPrivilegeNumber() outside of the query. You can also merge those Where queries into a single one:
var privilegeNumber = ui.GetPrivilegeNumber();
var filteredProducts = Products.Where(p =>
p.State.Contains("Bruikbaar")
&& p => p.Privilege <= privilegeNumber)
.ToList();
You can use other evaluation method inside LinQ. To simplified the code, you can use it in little old way of writing LinQ.
var uiPrivilege = ui.GetPrivilegeNumber();
var filteredProducts =(from p in Products
where p.State.Contains("Bruikbaar") && p.Privilege <= uiPrivilege
select p).ToList();
The above query generate same output but easy to understood.

Invalid 'where' condition. An entity member is invoking an invalid property or method

I've tried several methods to serach a client who have a propritaire.id in membresEquipeDuClient list, but each time I'm getting the "Invalid 'where' condition. An entity member is invoking an invalid property or method."-error!
I got the error in the second request,
The methods I've used :
List<TeamMembership> membresEquipeDuClient = (from k in context.CreateQuery<TeamMembership>()
where k.teamid == equipeDuClient.Id
select k).ToList();
var pRechercheNumeroClient = (from p in context.CreateQuery<Client>()
where membresEquipeDuClient.Any(a => a.systemuserid == p.proprietaire.Id)
select p).FirstOrDefault();
Any idea how to fix this?
Thx for all the help!
As said in the comment, Any is not supported, but Contains is. So you can do:
var systemUserIds =
(
from k in context.CreateQuery<TeamMembership>()
where k.teamid == equipeDuClient.Id
select k.systemuserid // Select the Id only
).ToList();
var pRechercheNumeroClient =
(
from p in context.CreateQuery<Client>()
where systemUserIds.Contains(p.proprietaire.Id)
select p
).FirstOrDefault();
I'm not familiar with Dynamics CRM, but I think you can remove the ToList from the first statement, so it will be an IQueryable and both statements will be executed as one expression.
var pRechercheNumeroClient = (from p in context.CreateQuery<Client>()
where membresEquipeDuClient.Select(a => a.systemuserid).Contains(p.proprietaire.Id)
select p).FirstOrDefault();

LINQ to Entities does not recognize the method 'System.String ToString(Int32)'

Hi I am using a linq query which is throwing the error LINQ to Entities does not recognize the method 'System.String ToString(Int32)' method, and this method cannot be translated into a store expression.
List<string> resultMap = (from item in mapResult
select Convert.ToString(item.ResultDE)).ToList();
Error is throwing in this below statement
List<Result_DE> resultList = (from result in db.Result_DE
where result.IsActive == "1"
&& resultMap.Contains(Convert.ToString(Convert.ToInt32(result.ID)))
select result).ToList();
please tell me the proper way of writing this query.
You cannot use these conversion functions in a LINQ to Entities statement, they cannot be translated to SQL, you need to do the conversions in memory. But I don't think you need to do that at all.
If you were just using the resultMap to get your resultList, filtered by Results of which the Id is present in mapResult, do the following:
var resultList = db.Result_DE
.Where(r => r.IsActive == "1" && mapResult.Any(mr => mr.ResultDE == r.ID));
.ToList();
If mapResult is an in-memory collection, instead of an IQueryable that is attached to the db context, you need to do the following:
var resultIds = mapResult.Select(mr => mr.ResultDE).ToList();
var resultList = db.Result_DE
.Where(r => r.IsActive == "1" && resultIds.Contains(r.ID));
.ToList();
Before you call any method (e.g. ToString()), you need to convert LINQ to Object using AsEnumerable().
if your item.ResultDE and result.ID is variable type of Int32,
why don directly create a List<Int32> ?
List<Int32> resultMap = (from item in mapResult
select item.ResultDE).ToList<Int32>();
List<Result_DE> resultList = (from result in db.Result_DE
where result.IsActive == "1"
&& resultMap.Contains(result.ID)
select result).ToList<Result_DE>();
Use SqlFunctions.StringConvert instead of Convert.ToString.
A similar question was asked and answered here

MVC search a LINQ query

I have a very simple query
var query = (from s in db.Stocks
select s).ToList();
and now basically I want to then search that query to see if any of the stock objects names in the query contain "a"
I have this
if(!string.IsNullOrEmpty(searchModel.Name) )
{
query = query.Where(x => x.Name.Contains(searchModel.Name));
}
but I am getting this error
Cannot implicity convert type "system.collections.generic.ienumerable<etc etc> to system.collections.generic.list
How can I search my query result?
Its ok I have the answer
I just need to add .ToList to the end of my query statement like so
if(!string.IsNullOrEmpty(searchModel.Name) )
{
query = query.Where(x => x.Name.Contains(searchModel.Name)).ToList();
}
The reason is because in the first query
var query = (from s in db.Stocks
select s).ToList();
you have fixed the data type of the variable query to be List (toList()) . Now when you query it again with Where it returns IEnumerable and can't be assigned to the type List . You can do it in one line as in below
var query = from s in db.Stocks
where s.contains(searchModel.Name)
select s
try
query = query.Where(x => x.Name.Contains(searchModel.Name)).ToList();
you can re-write the query as following:
var query = (from s in db.Stocks.ToList()
where !string.IsNullOrEmpty(searchModel.Name) ? s.Contains(searchModel.Name) : true
select s).ToList();
the new added line means: if SearchModel.Name is filled then search using it, otherwise do nothing
or you can keep your code as it, but add .ToList() after the table name, or remote .ToList() on the end of your query code which enforce the datatype of result

Error in Linq, Count()

I'm trying write this sql query to Linq:
SQL:
select c.course_name, count(s.s_name) as studenti from course c
join study_group g on g.course_id=c.id
join student s on s.study_group_id=g.id
group by c.course_name;
Linq:
var countStudents = (from s in ado.student //on g.id equals s.study_group_id
join g in ado.study_group on s.study_group_id equals g.id
join c in ado.course on g.course_id equals c.id
group s by c.course_name into cn
let count = cn.Count(co => co.s_name)
select new
{
c.course_name
course_name = cn.Key
});
and still I have an error at co => co.s_name
Error: Cannot implicitly convert type 'string' to 'bool'
Know anybody how to fix this ?
Thank you.
The SQL COUNT(column) aggregate function only counts not null values. The equivalent in LINQ would be to replace the line:
let count = cn.Count(co => co.s_name)
by
let count = cn.Count(co => co.s_name != null)
Of course, no guarantees on the generated SQL here. Either way, it is strange that a student's name may be null, though I have no intention of discussing your model.
Note
You won't be able to retrieve the desired count unless you select it in your code. Also, do check if students' names can be null, because in case they can't, just a cn.Count() would suffice.
Why do you need the Count clause in your LINQ statement? Just use a .Count() extension method on the IEnumerable that's returned from your query to get the count.
var count = countStudents.Count();

Categories