Problems with DevForce queries within a checked context - c#

We are in the process of switching over our codebase to have the Check for arithmetic overflow/underflow option turned on by default and we've run into problems with our DevForce queries.
I'm able to reproduce the problem with a very basic query such as this against the NorthwindIB database:
var coolProducts = em.Products.Where(p => p.UnitsInStock == 42).Execute();
By doing some debugging, it looks like DevForce is trying to add that query to the cache which involves making a hash code for the query. The class that does that hash code generation (ExpressionHashCodeCalculator) is missing a switch case for the ConvertChecked ExpressionType and so it throws an ArgumentException saying "Unknown Expression type".
It seems the compiler sprinkles that ConvertChecked thing all over the place in expressions when you are running in a checked context.

Thanks for reporting this. It will be fixed in the next release, due in March.

Related

Upgrading to EntityFramework 6.1.3 and now receiving context exceptions

I recently upgraded from Entity Framework 5 to Entity Framework 6.1.3.
The below code using multiple contexts of the same connection worked fine before in EF5:
var Ids = MyDbContext.MyObject.Select(x => x.Id).Take(5).AsEnumerable();
var myObjects = MyDbContext2.MyObject.Where(x => Ids.Contains(x.Id)).ToList();
In EF6, I receive:
The specified LINQ expression contains references to queries that are
associated with different contexts. Description: An unhandled
exception occurred during the execution of the current web request.
Please review the stack trace for more information about the error and
where it originated in the code.
Exception Details: System.NotSupportedException: The specified LINQ
expression contains references to queries that are associated with
different contexts.
What in Entity Framework changed to stop this from working? Is there anyway I can get this to work without changing code?
Change first line from .AsEnumerable() to .ToList().
https://msdn.microsoft.com/en-us/data/hh949853.aspx#_Query_Plan_Caching
According to this documentation, there were changes made to Contains processing in EF 6 to optimize the way the underlying SQL query is generated.
Just a shot in the dark without looking at EF6's code:
IEnumerable is generally a deferred execution that doesn't hit the database until you reference the data in some way. From the framework's point of view, that isn't a list of integers or longs, but a query that needs to be performed in a different context. Since it's in the middle of a query in a different context, the SQL parser is probably having trouble resolving it with their new way of doing things. IEnumerable is a sort of half way state between Queryable and loaded. I'd guess whatever changes they made for optimization do not perform the outstanding queries any longer, and it just immediately short circuits to an exception if the referenced object isn't part of the context, no matter what it is.
This is also why changing it to a List() allows it to work. You're working off of a list of primitives and not an unresolved query.
Why did they make the change? I suppose they have their reasons (even beyond optimization). One I can think of is that it prevents the query generation parts from modifying the loaded state of that IEnumerable to remove that possibly unwanted side effect.
You can add the ToDictionary():
var Ids = (
from x in MyDbContext.MyObject.Select()
where x.Contains(x.Id)
select x
).ToDictionary(x => x.Key).Keys.ToList();
var myObjects = (
from y in MyDbContext2.MyObject
where y => Ids.Contains(y.Id).ToList()
).ToList();
return myObjects;

String assignment mystic issue. Variable name affects behavior

I have the following code inside a method:
string username = (string)context["UserName"];
string un = (string)context["UserName"];
The problem is that the first string "username" is not assigned, while the second does.
To make it more strange, when I have stopped the debugging after the first line and copied the line to the Immediate window, dropping the varible type delaration, it was assigned succesfully.
I have made rebuild all and checked project properties which seems to be OK.
The context variable is a System.Configuration.SettingsContext, which is a hash table. To be more specific, I'm implementing a profile provider, the GetPropertyValues method.
I am using VS 2012 and .NET 4.5
EDIT:
I am using code contract in my project, which uses compile time code injection for runtime checking. I disabled it and all is working well. I'll try to remove contracts one by one to find which one is causing the problem.
What you are seeing is similar to a Code Contracts bug I saw before. I wrote something about it here a few months back. If you have this bug, you probably also have a lambda or LINQ expression in your method that uses username.
For future reference, this is the bug I saw:
I had in the same method a lambda expression capturing a local variable, lets say values, and a Contract.Requires() expression checking something completely unrelated. While debugging that method, the debugger shows in Locals the variable values twice, and reports the value of values always as null even when this is clearly not the case.
To reproduce:
static void Reproduction(string argument)
{
Contract.Requires(argument != null); // <-- (1)
int[] values = new int[1];
Debug.Assert(values != null);
Func<int, bool> d = i => values[i] >= 0; // <-- (2)
Console.WriteLine(values);
}
Put a breakpoint somewhere in this method after the assignment to values and ensure that the method gets called. When the debugger hits the breakpoint, look at the Locals list of Visual Studio for the duplicate variable. Hover the mouse over values to find that it gets reported as being null, something which is clearly not the case.
The problem disappears when removing either the contract (1) or the line with the lambda (2).
After investigating and desabling contracts I found that the problem appears only when runtime contracts checking is enabled and this contract appears:
Contract.Ensures(Contract.Result<System.Configuration.SettingsPropertyValueCollection>() != null);
If I delete this line, the code works, so it looks like code contracts bug, though I couldn't recreate it on a test project.

Linq: {"Operation could destabilize the runtime."}

In my App i when debuging a have this exception:
{"Operation could destabilize the runtime."} in the foreach loop:
foreach (var item in Model)
when i hover the model in debugmode the first time
i says :
ResultView=>Expending the result view will enumarate the enumarable
base=>Operation Could not destabilize the runtime.
after hovering a couple more times, a get the ResultView shows my data.
thats when i, in debugmode...
when i run my app without debugin it a overing over the Mode it throws this exception
what does this mean??
UPDATE
The model is IQueryable by it still doesnt work, only when i'm i debug mode
It possibly means that I made a mistake when implementing the code generator for expression trees. When an expression tree lambda is turned into a delegate, we spit IL dynamically into the delegate body. If that IL code is not well-formed and unverifiable, then running it could make the jitter generate bad code, and that could, in theory, destabilize the runtime. I thought we caught all the unverifiable code defects, but it is possible that a few slipped through.
If you have a small, simple, self-contained repro of the problem and it looks like it matches the diagnosis above, send me an email via the contact link on my blog, and I'll get a bug entered on the team that now owns the IL generation code. The ideal repro would just be code which generates an offending expression tree lambda, compiles it, and gets the exception.
Thanks!
check out this........
http://weblogs.asp.net/mnissen/archive/2009/05/07/quot-operation-could-destabilize-the-runtime-quot-error-with-asp-net-medium-trust-level-in-cassini-on-vista.aspx
Operation could destabilize the runtime?

"Index was outside the bounds of the array" when checking non-array variable

I have a class "Address" that has the following check:
if(thisAddress == null)
thisAddress = new Address();
When the code is run I get "Index was outside the bounds of the array" on the first line. If I remove the IF statement I get the error on the second line.
The class comes from Linq to SQL, but I have extended it. This worked before, I'm not sure why it started happening all of a sudden. thisAddress is a private variable in a UserControl.
Any ideas?
The code is not in sync with the binary.
Try recompiling the assembly that contains the usercontrol.
Has anything changed in the DB that you think can break the LINQ to SQL mapping?
Typically linq statements are executed lazily, or when they are used rather than when you wrote the link. Therefore it is entirely possible that the code executing behind the If statement is actually where the fault lies.
If this is the case then you could try stepping into the statement (it could be using an equality check on the thisAddress class) and the debugger should show you the linq being executed.
An alternative and what I use mostly, is setting the debugger to break when exceptions are thrown rather than when they are unhandled, this is a pretty good way of tracking down this sort of issue. (Debugger/Exceptions tick when thrown in VS).
hope that helps
Figured it out. Apparently I left out a crucial piece of information. The code is inside the get {} section for a control property. The error was a different line in the code (where I was using a split()), but the debugger pointed to the first line of the get{} statement.

Visual Studio debugging "quick watch" tool and lambda expressions

Why can't I use lambda expressions while debugging in “Quick watch” window?
UPD: see also
Link
Link
No you cannot use lambda expressions in the watch / locals / immediate window. As Marc has pointed out this is incredibly complex. I wanted to dive a bit further into the topic though.
What most people don't consider with executing an anonymous function in the debugger is that it does not occur in a vaccuum. The very act of defining and running an anonymous function changes the underlying structure of the code base. Changing the code, in general, and in particular from the immediate window, is a very difficult task.
Consider the following code.
void Example() {
var v1 = 42;
var v2 = 56;
Func<int> func1 = () => v1;
System.Diagnostics.Debugger.Break();
var v3 = v1 + v2;
}
This particular code creates a single closure to capture the value v1. Closure capture is required whenever an anonymous function uses a variable declared outside it's scope. For all intents and purposes v1 no longer exists in this function. The last line actually looks more like the following
var v3 = closure1.v1 + v2;
If the function Example is run in the debugger it will stop at the Break line. Now imagine if the user typed the following into the watch window
(Func<int>)(() => v2);
In order to properly execute this the debugger (or more appropriate the EE) would need to create a closure for variable v2. This is difficult but not impossible to do.
What really makes this a tough job for the EE though is that last line. How should that line now be executed? For all intents and purposes the anonymous function deleted the v2 variable and replaced it with closure2.v2. So the last line of code really now needs to read
var v3 = closure1.v1 + closure2.v2;
Yet to actually get this effect in code requires the EE to change the last line of code which is actually an ENC action. While this specific example is possible, a good portion of the scenarios are not.
What's even worse is executing that lambda expression shouldn't be creating a new closure. It should actually be appending data to the original closure. At this point you run straight on into the limitations ENC.
My small example unfortunately only scratches the surface of the problems we run into. I keep saying I'll write a full blog post on this subject and hopefully I'll have time this weekend.
Lambda expressions, like anonymous methods, are actually very complex beasts. Even if we rule out Expression (.NET 3.5), that still leaves a lot of complexity, not least being captured variables, which fundamentally re-structure the code that uses them (what you think of as variables become fields on compiler-generated classes), with a bit of smoke and mirrors.
As such, I'm not in the least surprised that you can't use them idly - there is a lot of compiler work (and type generation behind the scenes) that supports this magic.
You can't use lambda expressions in the Immediate or Watch windows.
You can however use System.Linq.Dynamic expressions, which take the form .Where("Id = #0", 2) - it doesn't have the full range of methods available in standard Linq, and doesn't have the full power of lambda expressions, but still, it's better than nothing!
The future has come!
Support for debugging lambda expressions has been added to Visual Studio 2015 (Preview at the time of writing).
Expression Evaluator had to be rewritten, so many features are missing: remote debugging ASP.NET, declaring variables in Immediate window, inspecting dynamic variables etc. Also lambda expressions that require calls to native functions aren't currently supported.
this might help:
Extended Immediate Window for Visual Studio (use Linq, Lambda Expr in Debugging)
http://extendedimmediatewin.codeplex.com/
http://dvuyka.spaces.live.com/blog/cns!305B02907E9BE19A!381.entry
All the best,
Patrick
Lambda expressions are not supported by the debugger's expression evaluator... which is hardly surprising since at compile time they are used to create methods (or Expression Trees) rather than expressions (take a look in Reflector with the display switched to .NET 2 to see them).
Plus of course they could form a closure, another whole layer of structure.
In VS 2015 you can do so now,this is one of the new feature they added.
If you still need to use Visual Studio 2013, you can actually write a loop, or lambda expression in the immediate window using also the package manager console window. In my case, I added a list at the top of the function:
private void RemoveRoleHierarchy()
{
#if DEBUG
var departments = _unitOfWork.DepartmentRepository.GetAll().ToList();
var roleHierarchies = _unitOfWork.RoleHierarchyRepository.GetAll().ToList();
#endif
try
{
//RoleHierarchy
foreach (SchoolBo.RoleHierarchy item in _listSoRoleHierarchy.Where(r => r.BusinessKeyMatched == false))
_unitOfWork.RoleHierarchyRepository.Remove(item.Id);
_unitOfWork.Save();
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
throw;
}
}
Where my GetAll() function is:
private DbSet<T> _dbSet;
public virtual IList<T> GetAll()
{
List<T> list;
IQueryable<T> dbQuery = _dbSet;
list = dbQuery
.ToList<T>();
return list;
}
Here I kept getting the following error, so I wanted to print out all the items in the various repositories:
InnerException {"The DELETE statement conflicted with the REFERENCE constraint \"FK_dbo.Department_dbo.RoleHierarchy_OranizationalRoleId\". The conflict occurred in database \"CC_Portal_SchoolObjectModel\", table \"dbo.Department\", column 'OranizationalRoleId'.\r\nThe statement has been terminated."} System.Exception {System.Data.SqlClient.SqlException}
Then, I find out how many records are in the department repository by executing this in the immediate window:
_unitOfWork.DepartmentRepository.GetAll().ToList().Count
Which returned 243.
So, if you execute the following in the package manager console, it prints out all the items:
PM> for($i = 0; $i -lt 243; $i++) { $a = $dte.Debugger.GetExpression("departments[$i].OrgagnizationalRoleId"); Write-Host $a.Value $i }
The author for the idea can be found here
To answer your question, here's the Visual Studio Program Manager's official explanation of why you can't do this. In short, because "it's really, really hard" to implement in VS. But the feature is currently in progress (as updated on Aug 2014).
Allow the evaluation of lambda expressions while debugging
Add your vote while you're there!

Categories