What is Opf3? Why is Opf3? How is Opf3? All these burning questions and issues discussed here.
 | |
| | I've been trying to do a bulk insert of data read from an xml file. In this example there are roughly 50,000 entities, each requiring at least 4 insert statements.
When trying to do the inserts within a transaction I keep getting strange errors. About half the time it will randomly try to do an Update instead of an Insert but produce a SQL statement without a Where clause, and the other half of the time the database will report a referrential integrity error because an Insert has been missed.
When I tried using .PersistChanges<>() on one entity at a time, without using a transaction, it all went through fine.
The main entities have a natural primary key, but some of the child properties have GUID key generated on the client with Guid.NewGuid(). From the symptoms it would seem to be something like the hashing algorithm used to determine the objects uniqueness in the datacontext produces the same hash for objects with different guids.
I made sure to use Identifier=true in the field attributes for the guid key members.
|
 | |
| | Hi!
I'll try to explain all of your problems 
Edward wrote: When trying to do the inserts within a transaction I keep getting strange errors. About half the time it will randomly try to do an Update instead of an Insert but produce a SQL statement without a Where clause, and the other half of the time the database will report a referrential integrity error because an Insert has been missed.
If the where clause is missing you forgot to add the identifier to the persistent that is updated.
Edward wrote: When I tried using .PersistChanges<>() on one entity at a time, without using a transaction, it all went through fine. That is as with each persist changes (without transaction) a new connection to the database is opened. This makes it slow and the Garbage Collector has time to collect the dead instances of the internal state objects.
If you are having this problem you should try to implement the ISelfContainingObject interface in your persistent object. This will move the state object from the ObjectContext to the persistent object instance itself, which means that each persistent instance holds it's own state.
The problem is strange, as we haven't had it before, and we are doing heavy inserts and updates too.
Opf3 is using the hashcode of the object to store it as key of the state object for the persistent object. It could be that the same hashcode is generated twice (for two different instances). But that is also very very weird, because Opf3 is checking (before getting the state object) if the instance (persistent instance) bound to the state object (we are using weak references here) is still alive. As long as the object is alive the .NET should never generate the same hashcode for two objects!
The code looks like this:
public object GetObjectTag(K key) { lock (this) { // Remove a dead item. if (_references.ContainsKey(key) && !_references[key].IsAliveTarget) { Remove(key); return null; }
CachedItem<V> item; if (!_references.TryGetValue(key, out item)) return null; return item.Tag; } }
The "tag" is the state object.
Did you override the GetHashCode method for your persistent objects?
|
 | |
| | No, I haven't overidden GetHashCode(), do you think it would help if I did?
The where clause is missing, but the point is it shouldn't be trying to do an update at all. All the data I am creating at this stage should be being inserted. It must be mixing the objects up, thinking that one version is a changed version of a previous one.
I think what I'm looking for is something like an ObjectWriter, the reverse of your ObjectReader class, that will just submit the objects to the database without trying to remember any of their state, at least for the bulk insert procedure.
Also is it worthwhile implementing IPopulateHelper on the objects I want to insert? The documentation says "populate them with data or retrieve data from them (the second option isn't supported until now!)", so does that men IPopulateHelper will only speed up data access and not inserts?
My next task is to do more inserts from another file, around 380,000 entities this time.
|
 | |
| | Hi,
Yes! An ObjectWriter is a great idea... I will see what I can do in that direction! Great idea.
The current version (3.0.8) supports both directions. The documentation is a little bit outdated on this information! I forgot to change it... IPopulateHelper makes it indeed faster to populate the persistent objects and get the data from the objects. You should give it a try!
It is strange that two objects have the same hashcode! I haven't seen that in any tests and haven't got any bug reports on this so far... Very strange. You could try to override the method and return your own value.
Christian
|
 | |
| | Do you have the source code of Opf3?
|