This is a migrated thread and some comments may be shown as answers.

Delete, Flush, and Requey

3 Answers 127 Views
Development (API, general questions)
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Paul
Top achievements
Rank 1
Paul asked on 04 Dec 2014, 09:39 PM
Hi again,

I'm trying to write some automated integration tests against my database objects, using Telerik Q2 2014 SP1.

The general form of a test is like this:

using (var context = new MyContext())
{
    // Create any related objects necessary for test
    context.FlushChanges();
 
    var entityUnderTest = new Entity();
    context.Add(entityUnderTest);  // Or update, or delete - whatever I'm testing.
    context.FlushChanges();
    context.Refresh(RefreshMode.OverwriteChangesFromStore, entityUnderTest);
 
    // Asserts, etc.
    context.ClearChanges();
}

I'm inside of a transaction and using FlushChanges() so that I get a full cleanup if the test fails.  This has worked great - except for one type of entity:

using (var context = new MyContext())
{
    // Create individual, organization, membership...
    context.FlushChanges();
 
    var entity = context.GetAll<Membership>()
        .Where(i => i.MemberId == individualId && i.MemberOfId == organizationId).Single();
    context.Delete(entity);
    context.FlushChanges();
  
    var deletedEntity = context.GetAll<Membership>()
        .Where(i => i.MemberId == individualId && i.MemberOfId == organizationId).SingleOrDefault();
    Assert.IsNull(deletedEntity);
  
    context.ClearChanges();
}


This is the only entity in my model with a composite key - a cross-reference table with some extra columns.  When I trace this at the database layer, the delete is executed (it happens to be a stored procedure), but the context doesn't re-query the database to assert the record was deleted.  The deletedEntity variable contains a reference to the entity.  They are both in the "Deleted" state, and attempts to access any properties throws an exception - as expected! - but I am used to getting a null back from the final SingleOrDefault() query.

Any advice on what I might be doing wrong?

3 Answers, 1 is accepted

Sort by
0
Kaloyan Nikolov
Telerik team
answered on 09 Dec 2014, 09:24 AM
Hi Paul,

The described behavior is by design. All entities are still accessible in the context with their updated states, if you have an updated entity it will stay tracked by the context in updated state, the same applies for the deleted entities. If you execute a query and a deleted entity fulfills the where clause it will be returned in deleted state. When the SaveChanges()/ClearChanges() is called all states will be applied and the deleted entities will not be deleted any more. 

Unfortunately there is no way to change the above behavior. You could write alternative AssernNullEntity method which will handle both cases - checking if it is null or if not it should be in deleted state. 

Should you have any additional questions do not hesitate to get back to us. 

Regards,
Kaloyan Nikolov
Telerik
 
OpenAccess ORM is now Telerik Data Access. For more information on the new names, please, check out the Telerik Product Map.
 
0
Paul
Top achievements
Rank 1
answered on 09 Dec 2014, 06:50 PM
Hi Kaloyan,

I understand why this would be expected behaviour, given how Telerik must cache the local objects.  Can you confirm that I should be inconsistent results based on the complexity of the keys?  It seems to vary based on the number of keys in the query:

// Find and delete with both PKs
// Test with both PKs
var deletedEntity = unitOfWork.GetAll<Membership>()
    .Where(i => i.MemberId == individualId && i.MemberOfId == organizationId).SingleOrDefault();
Assert.IsNull(deletedEntity);  // Fails, per above
 
// Find and delete with both PKs, test result with only one
var deletedEntity = unitOfWork.GetAll<Membership>()
    .Where(i => i.MemberId == individualId).SingleOrDefault();
Assert.IsNull(deletedEntity);  // Succeeds?
 
// Different object - only has one PK.
// Find and delete with PK, test with PK.
var deletedEntity = unitOfWork.GetAll<Individual>()
    .Where(i => i.Id = individualId).SingleOrDefault(); // Using the only PK on the object
Assert.IsNull(deletedEntity); // Succeeds?


0
Kaloyan Nikolov
Telerik team
answered on 12 Dec 2014, 02:07 PM
Hello Paul,

Your first example is expected to fail as you query the object by its Id and it is loaded in the context. 
The second succeeds because not all PKs are used in the query and thus it is executed against the DB as such query could return more than one entity.
For the third example it is supposed to fail too. You can validate this with the attached sample application. If that is not working for you then should be something with the setup or with the usage. Could you please send the exact code how you find and delete the entity plus the mapping.

To be able to attach the requested files I've converted your ticket to Product Feedback. 

Looking forward for your additional input.

Regards,
Kaloyan Nikolov
Telerik
 
OpenAccess ORM is now Telerik Data Access. For more information on the new names, please, check out the Telerik Product Map.
 
Tags
Development (API, general questions)
Asked by
Paul
Top achievements
Rank 1
Answers by
Kaloyan Nikolov
Telerik team
Paul
Top achievements
Rank 1
Share this question
or