I have identified the problem:
My tables all use a Guid as the primary key. In InitClassEmpty I set this value to a new Guid, so that new objects will always have a guid. When I retrieve an object and change another field, llblgen is treating the PK as changed. I removed the guid initialization from InitClassEmpty and that solved the problem.
However, I'd like to be able to initialize keys like this so that I don't have to remember to initialize the value every time I create a new object.
I reproduced this in a simple project. I have a BaseObject and a DerivedObject that inherits from it, linked by the ObjectID column.
In the code, I just retrieved all BaseObjects and updated a field:
DataAccessAdapter adapter = new DataAccessAdapter(true);
UnitOfWork2 uow = new UnitOfWork2();
EntityCollection<MyBaseObjectEntity> objects = new EntityCollection<MyBaseObjectEntity>(new MyBaseObjectEntityFactory());
adapter.FetchEntityCollection(objects, null);
foreach (MyBaseObjectEntity obj in objects)
{
obj.ValueB = DateTime.Now.ToString();
uow.AddForSave(obj);
}
try
{
uow.Commit(adapter, true);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return;
}
adapter.CloseConnection();
Here's the trace:
Current persisted entity info:
Entity: TestProject.EntityClasses.MyDerivedObjectEntity. ObjectID: 29ce5c1f-ab0c-4090-9dfc-1decc82d138a
PrimaryKey field: ObjectId. Type: System.Guid. Value: 74b1a17e-5d05-4c9f-af49-f1904e07fe52
PrimaryKey field: ObjectId. Type: System.Guid. Value: 74b1a17e-5d05-4c9f-af49-f1904e07fe52
Method Enter: CreateUpdateDQ(4)
Method Enter: CreateSingleTargetUpdateDQ(4)
Generated Sql query:
Query: UPDATE [testdb].[dbo].[BaseObject] SET [ObjectID]=@ObjectId_BaseObjectEntity,[ValueB]=@ValueB WHERE ( [testdb].[dbo].[BaseObject].[ObjectID] = @ObjectId_BaseObjectEntity1)
Parameter: @ObjectId_BaseObjectEntity : Guid. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: 74b1a17e-5d05-4c9f-af49-f1904e07fe52.
Parameter: @ValueB : String. Length: 50. Precision: 0. Scale: 0. Direction: Input. Value: "4/28/2009 10:25:47 AM".
Parameter: @ObjectId_BaseObjectEntity1 : Guid. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: 8ffdfe3f-8cf4-4b54-8c38-069ed803b669.
Method Exit: CreateSingleTargetUpdateDQ(4)
Method Enter: CreateSingleTargetUpdateDQ(4)
Generated Sql query:
Query: UPDATE [testdb].[dbo].[DerivedObject] SET [ObjectID]=@ObjectId WHERE ( [testdb].[dbo].[DerivedObject].[ObjectID] = @ObjectId2)
Parameter: @ObjectId : Guid. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: 74b1a17e-5d05-4c9f-af49-f1904e07fe52.
Parameter: @ObjectId2 : Guid. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: 8ffdfe3f-8cf4-4b54-8c38-069ed803b669.
Method Exit: CreateSingleTargetUpdateDQ(4)
Method Exit: CreateUpdateDQ(4)
Method Enter: DataAccessAdapterBase.ExecuteActionQuery
Method Enter: DataAccessAdapterBase.OpenConnection
Method Exit: DataAccessAdapterBase.OpenConnection
Method Exit: DataAccessAdapterBase.ExecuteActionQuery
Method Enter: DataAccessAdapterBase.Rollback
Method Enter: DataAccessAdapterBase.Reset
Method Exit: DataAccessAdapterBase.Reset
Method Exit: DataAccessAdapterBase.Rollback
Method Exit: UnitOfWork2.Commit(2)
An exception was caught during the execution of an action query: The UPDATE statement conflicted with the REFERENCE constraint "FK_DerivedObject_BaseObject". The conflict occurred in database "testdb", table "dbo.DerivedObject", column 'ObjectID'.
The statement has been terminated.. Check InnerException, QueryExecuted and Parameters of this exception to examine the cause of this exception.