Edit: This is not a problem with ignorance of basic programming (such as trying to dereference a null object reference).
Edit: Added the stack trace from EF within Linqpad.
Using EF6, I have a very simple query :
var menu = dbcontext.Tree.Where(t => t.Left > 2 && t.Right < 10).ToList();
This worked right up until it mysteriously stopped. dbcontext.Tree is a view in SQL Server 2012. Using Linqpad5, I get the results I expect using its built-in connection. Setting up an EF connection to my project, I get the NRE. Checking the SQL, I can copy and paste that into a SQL query window and get the proper results. I get an NRE without the Where call, also.
I've tried updating my model from database to refresh anything. I've tried removing the view from the model and updating. I've tried deleting the model entirely and recreating it. I've restarted Visual Studio AND my computer. I get the same NRE for the query. I don't know what else I can try, and this NRE makes no sense to me at all, given I get the results I expect using everything but EF. I'd chalk it up to a bug with EF if I didn't see it working previously.
Has anyone dealt with this? Searching online for this specific set of circumstances has produced nothing.
Stack Trace :
at System.Data.Entity.Core.EntityKey.AddHashValue(Int32 hashCode, Object keyValue)
at System.Data.Entity.Core.EntityKey.GetHashCode()
at System.Collections.Generic.GenericEqualityComparer`1.GetHashCode(T obj)
at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, TValue& value)
at System.Data.Entity.Core.Objects.ObjectStateManager.TryGetEntityEntry(EntityKey key, EntityEntry& entry)
at System.Data.Entity.Core.Objects.ObjectStateManager.FindEntityEntry(EntityKey key)
at System.Data.Entity.Core.Common.Internal.Materialization.Shaper.HandleEntityAppendOnly[TEntity](Func`2 constructEntityDelegate, EntityKey entityKey, EntitySet entitySet)
at lambda_method(Closure , Shaper )
at System.Data.Entity.Core.Common.Internal.Materialization.Coordinator`1.ReadNextElement(Shaper shaper)
at System.Data.Entity.Core.Common.Internal.Materialization.Shaper`1.SimpleEnumerator.MoveNext()
at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
The problem is that your Model (Tree in your example above) has one ore more properties that are not nullable (and possibly also marked as not nullable in the mapping) but the corresponding column in the data store is nullable. This exception would only manifest itself as soon as there was a record being retrieved that had a null value for one of those column(s).
Model fix - When updating the model be sure to use Nullable<T> or ? for nullable value types and if you have mappings defined (either via attributes or in types that inherit EntityTypeConfiguration) also specify that the property is optional there.
Data store fix - Alternatively change the data store schema and data to align it with what is expected in the model.
Related
I read the stack-trace and found that the error comes from oracle.jbo.EntityImpl.lock(). I read that is caused by RowInconsistentException. So the problem is data difference between my database and OAF page.
I put a break-point in the beginning of the method. I saw three interesting child objects: mData, mOrigData and mChanged. I saw that in my case mData content is identical to the database and mOrigData differes. How should I interpret it?
I found that mData means state before OAF operations, and mOrigData - state afterwards. mChanged contains ids of changed attributes. In my case I already had a non-null value in the database (non-null in mData) but on the page I was losing that value and tried to put null into the database (null in mOrigData). The framework decided that it was wrong.
I also had another case: updated_at attribute in the database was larger than in the mData object. It turned out that the database processed the row in the background after 2 seconds, but OAF read the row earlier. When I was trying to commit, OAF found that its state is older in the database and threw the same error.
This one is making me crasy : I have an EF model built upon a database that contains a table named Category with 6 rows in it.
I want to display this in a drop down list in WPF, so I need to bind it to the Categories.Local Observable collection.
The problem is that this observable collection never receives the content of the database table. My understanding is that the collection should get in sync with the database when performing a query or saving data with SaveChanges() So I ran the followin 2 tests :
Categories = _db.Categories.Local;
// test 1
Debug.WriteLine(_db.Categories.Count());
Debug.WriteLine(_db.Categories.Local.Count());
// test 2
_categories.Add(new Category() { CategoryName = "test" });
_db.SaveChanges();
Debug.WriteLine(_db.Categories.Count());
Debug.WriteLine(_db.Categories.Local.Count());
Debug.WriteLine(_categories.Count());
The test 1 shows 6 rows in the database, and 0 in local.
The test 2 shows 7 rows in the database, and 1 in local (both versions)
I also atempted to use _db.Category.Load() but as expected, it doesn't work because it is db first, not code first.
I also went through this page https://msdn.microsoft.com/en-us/library/jj574514(v=vs.113).aspx, created an object-based data source and linked my combo box to it, without success.
Does anyone know what I am doing wrong?
Thank you in advance for your help.
The DbSet<T> class is IQueryable<T>, hence DbSet<T>.Count() method maps to Queryable.Count<T> extension method, which in turn is translated to SQL query and returns the count of the records in the database table without loading anything into db context local cache.
While DbSet<T>.Local simply gives you access to the local cache. It contains the entities that you added as well as the ones being loaded by query that returns T instances (or other entities referencing T via navigation property). In order to fully load (populate) the local cache, you need to call Load:
_db.Categories.Load();
The Load is a custom extension method defined in QueryableExtensions class, so you need to include
using System.Data.Entity;
in order to get access to it (as well as to typed Include, XyzAsync and many other EF extension methods). The Load method is equivalent of ToList but without overhead of creating additional list.
Once you do that, the binding will work. Please note that the Local will not reflect changes made to the database through different DbContext instances or different applications/users.
I am having problems saving database records using Linq in visual studio 2010 and sql server 2008.
My problem is that when I am editing some records I sometimes check the original database record for validation purposes, only the original entry seems to be updated in real time - I.e. it is already exactly the same as the edited record, before I have submitted the changes!
Could anyone suggest an effective method of coping with this? I have tried using a 2nd database connection or a 2nd data repository to call the original record from the db but it appears to be already changed when I debug it.
public void SaveobjectEdit(object objectToEdit)
{
object originalObject = GetobjectById(objectToEdit.Id);
if (originalObject.objectStatus != objectToEdit.objectStatus)
{
originalObject.objectStatus = objectToEdit.objectStatus;
}
SaveChanges();
}
The save changes just calls _db.SubmitChanges(); by the way
Has no one got any ideas for the above question?
I hope I was clear - for validation purposes I would like to compare an original database record with one that I am editing. The problem is that when I edit a record and then attempt to retrieve the original record before saving - the original record is exactly the same as the edited record.
If you're trying to retrieve the original record in code, from the same 'context' using the same access method, then it will contain the updated object. Rather than ask why you're doing this or what you're trying to achieve, I'll instead explain how I understand the data context / object context to work (in a very loose and vague fashion).
The context is something like an in-memory representation of your database, where everything is lazy-loaded. When you instantiate the context you're given an object which represents your data model (of course it may not be a 1-1 representation, and can contain various abstractions). Nothing is loaded into the context until necessary; any queries you write stay as queries until you peer in their results. When you access an item (e.g. GetobjectById(objectToEdit.Id)) the item is loaded into the context from the database and you can get and set its properties at your leisure.
Now, the important part: When you access an item, if it has already been loaded into the context then that in-memory object is returned. The context doesn't care about checking changes made; the changes won't be persisted to the database until you submit, but they remain in memory.
The way to refresh the in-memory objects is to call the Refresh method on the context. Try this test:
using (var db = new MyObjectContext())
{
var item = db.Items.First();
item.Name = "testing this thing";
Console.WriteLine(db.Shifts.First().Name);
db.Refresh(System.Data.Objects.RefreshMode.StoreWins, db.Items);
Console.WriteLine(db.Shifts.First().Name);
}
I believe this pattern makes a lot of sense and I'm not sure it could work any other way. Consider this:
foreach (var item in db.Items)
{
item.Name = "test";
}
Assert(db.Items.All(item => item.Name == "test"));
Would you want the Assert to fail? Should those items be reloaded? I don't believe so. I'm looking at the items in my context, not in the database. I'm not checking whether items in the database have been updated, but instead that I've updated all the items in the context of my code.
This is a good reason why I don't use MyObjectContext db - it is not a 'db' or a database connection. It's a context within which I can change whatever I want, so I name it such: MyObjectContext context.
I'm using silverlight 4 with ria serivces ..
I got an error said :
The type 'eLab.Web.SessionsHWFile' exists in both 'eLab.Web.dll' and 'DataContractSurrogates_c96b3601-cd13-4049-93bb-e7b3f59a4fd9'
where eLab.Web is the aspx web project that hosts the silverlight project, and SessionsHWFile is an edmx entity ,it's not a real table in DB, it's VIEW. I dragged a grid from the data source and doped it in XAML user control, and used a query to get the data from stored procedure in DB, but I'm getting the above error when I debug the code and expand the results view :
(source: 0zz0.com)
I did this ,adding a view and getting the results from SP in DB, like a million time and nothing happened until this time ..
**I think I knew were the problem is ..
I discovered that you can't name two "riaControls:DomainDataSource" with the same Name, even if they're int different xaml pages.
Honestly I don't know why yet, but that's how I fixed the problem ..
Just change the Name property of the "riaControls:DomainDataSource" ...**
Here is the scenario:
I have a winforms application using NHibernate. When launched, I populate a DataGridView with the results of a NHibernate query. This part works fine. If I update a record in that list and flush the session, the update takes in the database. Upon closing the form after the update, I call a method to retrieve a list of objects to populate the DataGridView again to pick up the change and also get any other changes that may have occurred by somebody else. The problem is that the record that got updated, NHibernate doesn't reflect the change in the list it gives me. When I insert or delete a record, everything works fine. It is just when I update, that I get this behavior. I narrowed it down to NHibernate with their caching mechanism. I cannot figure out a way to make NHibernate retrieve from the database instead of using the cache after an update occurs. I posted on the NHibernate forums, but the suggestions they gave me didn't work. I stated this and nobody replied back. I am not going to state what I have tried in case I didn't do it right. If you answer with something that I tried exactly, I will state it in the comments of your answer.
This is the code that I use to retrieve the list:
public IList<WorkOrder> FindBy(string fromDate, string toDate)
{
IQuery query = _currentSession.CreateQuery("from WorkOrder wo where wo.Date >= ? and wo.Date <= ?");
query.SetParameter(0, fromDate);
query.SetParameter(1, toDate);
return query.List<WorkOrder>();
}
The session is passed to the class when it is constructed. I can post my mapping file also, but I am not sure if there is anything wrong with it, since everything else works. Anybody seen this before? This is the first project that I have used NHibernate, thanks for the help.
After your update, Evict the object from the first level cache.
Session.Update(obj);
Session.Evict(obj);
You may want to commit and/or flush first.
what about refresh? - see 9.2. Loading an object of the docs:
"sess.Save(cat);
sess.Flush(); //force the SQL INSERT
sess.Refresh(cat); //re-read the state (after the trigger executes)
"