I was using the same query before it was working fine. Then I decided to use complied query. So I had to make few changes to the code.
Now when I try to execute the code, I get the error message "Unsupported overload used for query operator 'Where'.
The where clause which I generate from “approvalHelper.GetWhereClauseForApprovalSimpleSearch();” has been tested and works fine.
Only doesn't work for the complied query part as shown in my code
code :
// Complied Query Class
public static class CompliedQuery
{
public static Func<GDataContext, Expression<Func<View_ApprovalSimple, bool>>, IQueryable<View_ApprovalSimple>> getApprovalSimple =
CompiledQuery.Compile<GDataContext, Expression<Func<View_ApprovalSimple, bool>>, IQueryable<View_ApprovalSimple>>(
(db, whereclause) => (from results in db.View_ApprovalSimples.AsExpandable().Where(whereclause)
select results));
}
// this is what is passed into the where clause; Body = {(vas.siteId = 1)}
//the Calling code
public static List<View_ApprovalSimple> GetApprovalSimple(ApprovalsSearchHelperClass _approvalHelper)
{
Expression<Func<View_ApprovalSimple, bool>> whrClause = approvalHelper.GetWhereClauseForApprovalSimpleSearch();
//whrclause; Body = {(vas.siteId = 1)}
try
{
using (GDataContext db = new GDataContext())
{
if (whrClause != null)
{
var varResults = CompliedQuery.getApprovalSimple(db, whrClause);
return varResults.ToList();
}
}
}
catch (Exception ex)
{
// code to handle error
}
finally
{
}
return null;
}
Any idea what new changes I might have to implement?
Thanks in advance.
Check the namespaces (start off by copying them all from CompliedQuery) to the calling class.
First I was a bit sceptical about this, ran out of options so I finally tried it and it did work.
please follow the link to see answer
Steve's Blog
Great work Steve.
Related
Going from a lambda to an Expression is easy using a method call...
public void GimmeExpression(Expression<Func<T>> expression)
{
((MemberExpression)expression.Body).Member.Name; // "DoStuff"
}
public void SomewhereElse()
{
GimmeExpression(() => thing.DoStuff());
}
But I would like to turn the Func in to an expression, only in rare cases...
public void ContainTheDanger(Func<T> dangerousCall)
{
try
{
dangerousCall();
}
catch (Exception e)
{
// This next line does not work...
Expression<Func<T>> DangerousExpression = dangerousCall;
var nameOfDanger =
((MemberExpression)dangerousCall.Body).Member.Name;
throw new DangerContainer(
"Danger manifested while " + nameOfDanger, e);
}
}
public void SomewhereElse()
{
ContainTheDanger(() => thing.CrossTheStreams());
}
The line that does not work gives me the compile-time error Cannot implicitly convert type 'System.Func<T>' to 'System.Linq.Expressions.Expression<System.Func<T>>'. An explicit cast does not resolve the situation. Is there a facility to do this that I am overlooking?
Ooh, it's not easy at all. Func<T> represents a generic delegate and not an expression. If there's any way you could do so (due to optimizations and other things done by the compiler, some data might be thrown away, so it might be impossible to get the original expression back), it'd be disassembling the IL on the fly and inferring the expression (which is by no means easy). Treating lambda expressions as data (Expression<Func<T>>) is a magic done by the compiler (basically the compiler builds an expression tree in code instead of compiling it to IL).
Related fact
This is why languages that push lambdas to the extreme (like Lisp) are often easier to implement as interpreters. In those languages, code and data are essentially the same thing (even at run time), but our chip cannot understand that form of code, so we have to emulate such a machine by building an interpreter on top of it that understands it (the choice made by Lisp like languages) or sacrificing the power (code will no longer be exactly equal to data) to some extent (the choice made by C#). In C#, the compiler gives the illusion of treating code as data by allowing lambdas to be interpreted as code (Func<T>) and data (Expression<Func<T>>) at compile time.
private static Expression<Func<T, bool>> FuncToExpression<T>(Func<T, bool> f)
{
return x => f(x);
}
What you probably should do, is turn the method around. Take in an Expression>, and compile and run. If it fails, you already have the Expression to look into.
public void ContainTheDanger(Expression<Func<T>> dangerousCall)
{
try
{
dangerousCall().Compile().Invoke();;
}
catch (Exception e)
{
// This next line does not work...
var nameOfDanger =
((MemberExpression)dangerousCall.Body).Member.Name;
throw new DangerContainer(
"Danger manifested while " + nameOfDanger, e);
}
}
public void SomewhereElse()
{
ContainTheDanger(() => thing.CrossTheStreams());
}
Obviously you need to consider the performance implications of this, and determine if it is something that you really need to do.
If you sometimes need an expression and sometimes need a delegate, you have 2 options:
have different methods (1 for each)
always accept the Expression<...> version, and just .Compile().Invoke(...) it if you want a delegate. Obviously this has cost.
NJection.LambdaConverter is a library that converts a delegate to an expression
public class Program
{
private static void Main(string[] args) {
var lambda = Lambda.TransformMethodTo<Func<string, int>>()
.From(() => Parse)
.ToLambda();
}
public static int Parse(string value) {
return int.Parse(value)
}
}
You can go the other way via the .Compile() method however - not sure if this is useful for you:
public void ContainTheDanger<T>(Expression<Func<T>> dangerousCall)
{
try
{
var expr = dangerousCall.Compile();
expr.Invoke();
}
catch (Exception e)
{
Expression<Func<T>> DangerousExpression = dangerousCall;
var nameOfDanger = ((MethodCallExpression)dangerousCall.Body).Method.Name;
throw new DangerContainer("Danger manifested while " + nameOfDanger, e);
}
}
public void SomewhereElse()
{
var thing = new Thing();
ContainTheDanger(() => thing.CrossTheStreams());
}
Expression<Func<T>> ToExpression<T>(Func<T> call)
{
MethodCallExpression methodCall = call.Target == null
? Expression.Call(call.Method)
: Expression.Call(Expression.Constant(call.Target), call.Method);
return Expression.Lambda<Func<T>>(methodCall);
}
JB Evain from the Cecil Mono team is doing some progress to enable this
http://evain.net/blog/articles/2009/04/22/converting-delegates-to-expression-trees
Change
// This next line does not work...
Expression<Func<T>> DangerousExpression = dangerousCall;
To
// This next line works!
Expression<Func<T>> DangerousExpression = () => dangerousCall();
I'm experimenting with some queries to find out the best way to get performance gains.
I know that using IQueryable is preferable to performing Linq to Sql or Linq to Entity database queries and that IEnumerable is best used for linq to Objects, Linq to xml, and in memory processing.
I have a linq query as follows on my WCF service. When I try and modify the Controller method that calls this, I get the following design time compile error:
Cannot implicitly convert type 'YeagerTechModel.DropDownLists.ProjectDescription[]' to 'System.Linq.IQueryable'
Note that the ProjectDescription object is defined as follows:
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
namespace YeagerTechModel.DropDownLists
{
[DataContract]
[Serializable]
public partial class ProjectDescription
{
[DataMember]
public Int16 ProjectID { get; set; }
[DataMember]
public String Description { get; set; }
}
}
Here is the DB method call:
public IQueryable<ProjectDescription> GetProjectDropDownList()
{
try
{
using (YeagerTechEntities DbContext = new YeagerTechEntities())
{
DbContext.Configuration.ProxyCreationEnabled = false;
DbContext.Database.Connection.Open();
IQueryable<ProjectDescription> project = DbContext.Projects.Where(w => w.Notes != null).Select(s =>
new ProjectDescription()
{
ProjectID = s.ProjectID,
Description = s.Description
}
);
return project;
}
}
catch (Exception ex)
{
throw ex;
}
}
Here is the code in the Controller method:
IQueryable<ProjectDescription> projectDdl = db.GetProjectDropDownList();
Now, prior to this experimentation after reading up on the performance gains of IQueryable, etc, the original method to get the data from the database was as follows:
public List<ProjectDescription> GetProjectDropDownList()
{
try
{
using (YeagerTechEntities DbContext = new YeagerTechEntities())
{
DbContext.Configuration.ProxyCreationEnabled = false;
DbContext.Database.Connection.Open();
var project = DbContext.Projects.Where(w => w.Notes != null).Select(s =>
new ProjectDescription()
{
ProjectID = s.ProjectID,
Description = s.Description
}
);
List<ProjectDescription> myProjects = new List<ProjectDescription>();
myProjects = project.ToList();
return myProjects;
}
}
catch (Exception ex)
{
throw ex;
}
}
The code in the Controller was as follows:
IEnumerable<ProjectDescription> projectDdl = db.GetProjectDropDownList();
First question is:
Many queries use the var keyword to infer the type coming back. Which one to use when calling the DB to retrieve records? The "var" syntax or the "IQuerable" syntax"?
The second thing I noticed is that on the Controller side, for a collection, it always expects a List object which is easily converted to IEnumerable.
So, based on this premise, I gather that my optimum solution would be as follows:
For the DB method call:
public List<ProjectDescription> GetProjectDropDownList()
{
try
{
using (YeagerTechEntities DbContext = new YeagerTechEntities())
{
DbContext.Configuration.ProxyCreationEnabled = false;
DbContext.Database.Connection.Open();
IQueryable<ProjectDescription> project = DbContext.Projects.Where(w => w.Notes != null).Select(s =>
new ProjectDescription()
{
ProjectID = s.ProjectID,
Description = s.Description
}
);
List<ProjectDescription> myProjects = new List<ProjectDescription>();
myProjects = project.ToList();
return myProjects;
}
}
catch (Exception ex)
{
throw ex;
}
}
For the code snippet in the Controller, it should be as follows and everything works fine:
IEnumerable<ProjectDescription> projectDdl = db.GetProjectDropDownList();
So, if IQueryable gives better performance (specifically on filtering and supports lazy loading), why not use the last DB method instead of the "var" keyword?
Can somebody help explain what should be the optimum scenario?
Whether you use var or take the time to type out the variable's type isn't really an issue. Your second and third examples both compile into exactly the same code.
Your first implementation, however, is much better than the other two. Your first method return a query. The other two return the results of that query.
So the first implementation allows the caller to apply further filters/mappings/manipulations of that query and have them be reflected in the database query that is called, rather than on the results in memory. It also means that you're deferring actually executing that query until later on when you need it, rather than right now.
That implementation does have a flaw though; you're deferring execution but also disposing of the underlying context before the query is executed. You'll need to scope your context at a "higher" level to ensure that it has not yet been disposed of until after the query has been executed.
As for the error, you haven't shown enough information to see where the problem lies, but you should make an effort to fix it without just doing all of your data manipulation in your application instead of in your database.
Side note: there's no point in catching an exception just to rethrow it. You're doing nothing productive but clearing out the stack trace. Just don't catch the exception in the first place if you have nothing to do with it.
try
{
var orderedListOfRfidTags = uow.RfidTags.ToList().OrderBy(t => int.Parse(t.Number));
return View(orderedListOfRfidTags);
}
catch
{
var orderedListOfRfidTags = uow.RfidTags.OrderBy(t => t.Number).ToList();
return View(orderedListOfRfidTags);
}
MVC3 - in Release mode this will still fail on the first line var ordreedListOfRfidTags...
I wonder why try catch isn't trying and catching?
then pressing F10 it goes to here.. which is part of my ORM wrapper... hmm I wonder if this is the problem.
protected override void OnResultExecuted(ResultExecutedContext filterContext)
{
if (_unitOfWorkScope != null)
{
_unitOfWorkScope.Dispose();
}
base.OnResultExecuted(filterContext);
}
The delegate passed to OrderBy is not invoked until you try to access the elements in the list.
So I think the error is not caught because your collection is not enumerated until the view is being rendered, after the action method has returned.
This is a bad design; you shouldn't have any code in your catch that could potentially throw another exception.
If I'm understanding your code, you want to attempt to parse the RFID to an int, but fall back on string as your sort if a failure?
If you can't gaurentee that the Numbers of the RfidTags won't be a number (which seems a silly naming structure), then I'd leave it as a string sort and ditch the int parsing
The answer was that LightSpeed was failing out. Once the support was added (very quickly - awesome product!) it all worked fine:
// trying to convert to an int.. if fail, use string
// need up to date nightly build of LS3.1 for this to work
// otherwise trycatch will fail due to LS crashing out.
try
{
var orderedListOfRfidTags = uow.RfidTags
.OrderBy(t => Convert.ToInt32(t.Number))
.ToList();
return View(orderedListOfRfidTags);
}
catch
{
var orderedListOfRfidTags = uow.RfidTags
.OrderBy(t => t.Number)
.ToList();
return View(orderedListOfRfidTags);
}
Hi could you help me with this error?
Cannot access a disposed object.
Object name: 'DataContext accessed after Dispose.'.
in my GUI
private void InitializePage()
{
cbCategory.DataSource = stock.StockCategory.Get();
}
in Datamodel
public IEnumerable<StockCategory> Get()
{
using (leDataContext db = new leDataContext())
{
try
{
var r = from s in db.StockCategories
select s;
return r;
}
catch (Exception ex)
{
Logger.Error(typeof(StockCategory), ex.ToString());
throw;
}
}
}
You're disposing the DataContext but returning something that still depends on it.
Options:
Don't dispose the DataContext. I know this sounds weird, but guidance from the LINQ to SQL team (well, Matt Warren) has indicated that in most cases (i.e. if you're not doing anything out of the ordinary) disposal is not required
Call ToList() inside the Get() method's using block.
Note that using a query expression with just a degenerate query is reasonably pointless. (If this is within your own code, even the implicit Select(s => s) won't actually be useful.)
I would suggest changing your method to:
public IList<StockCategory> GetAllStockCategories()
{
using (leDataContext db = new leDataContext())
{
return db.StockCategories.ToList();
}
}
Because of lazy-loading there, the query isn't really executed on the linq statement line. It is executed when you loop over it, or in this case - when you run ToList on it.
When it is executed it must be inside the data context... which is not the case here. You can either return a List from the Get method or insert the setting of the cbCategory.DataSource value into the using (leDataContext...) scope.
I found something quite odd(I think!). If I try to put a breakpoint in the yes() method, it will never pause the program when it executes the function. If I try to do the same to any other line of code, it will work just as expected. Is it a bug, or is there something that's escaping me?
The filter will return the 2 objects, everything seems to be working as expected except the debugger.
private void Form1_Load(object sender, EventArgs e) {
List<LOL> list = new List<LOL>();
list.Add(new LOL());
list.Add(new LOL());
IEnumerable<LOL> filter = list.Where(
delegate(LOL lol) {
return lol.yes();
}
);
string l = ""; <------this is hit by the debugger
}
class LOL {
public bool yes() {
bool ret = true; <---------this is NOT hit by the debugger
return ret;
}
}
Enumerable.Where is a lazy operator -- until you call something that goes through the IEnumerable returned by where (ie. calling .ToList() on it), your function won't get called.
Try changing your code to this and see if it gets called:
....
IEnumerable<LOL> filter = list.Where(
delegate(LOL lol) {
return lol.yes();
}
).ToList();
string l = "";
You have to materialize the list. Add a ...
filter.ToList();
... after the declaration and you will hit your breakpoint. About the best discussion I've seen on that is here. It does lazy evaluation much better justice than I could do.
As others have said, you have just defined your criteria but have not asked it for execution. This is called lazy loading (guys, correct me if I am wrong).
Run a foreach loop on filter to see what happens.
Jonathan is correct.
Try running this console application and set breakpoints where indicated to see it clearly.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<LOL> list = new List<LOL>();
list.Add(new LOL());
list.Add(new LOL());
IEnumerable<LOL> filter = list.Where(
delegate(LOL lol)
{
return lol.yes();
}
);
// Breakpoint #2 will not have been yet.
Console.Write("No Breakpoint"); // Breakpoint #1
// (Breakpoint #2 will now be hit.)
Console.Write("Breakpoint! " + filter.Count());
}
class LOL
{
public bool yes()
{
bool ret = true; // Breakpoint #2
return ret;
}
}
}
}