2
votes

I have an entity with a composite primary key that models a many to many relationship:

public class ActualAnswer
{
    [Key]
    [Column(Order = 0)]
    public int AnsweredQuestionID { get; set; }

    [Key]
    [Column(Order = 1)]
    public int AnswerID { get; set; }

}

If I delete one of these entities in my client application using Breeze, it's state is set to Deleted:

function deleteEntity(entity) {
    var ea = entity.entityAspect;
    ea.setDeleted();
}

If the user changes their mind I currently try to recreate the entity:

createEntity("ActualAnswer", {
    AnsweredQuestionID: answeredquestionid,
    AnswerID: answerid
});

which calls this function using my Breeze EntityManager:

function createEntity(entityType, initialValues) {
    var entity = manager.createEntity(entityType, initialValues)
    return entity;
}

However, that causes an error:

A MergeStrategy of 'Disallowed' does not allow you to attach an entity when an entity with the same key is already attached: ActualAnswer:#etc

It is true, we already have an entity with the same key - but it is in a "Deleted" state.

So, how can I retrieve that and undelete it?

Alternatively, can I safely use a different merge strategy? What are the pitfalls I need to look out for? Can I minimise the risk by using the merge strategy on this particular entity only?

2

2 Answers

1
votes

This is the only way I could find to retrieve deleted items from the cache and undelete them:

//A MergeStrategy of 'Disallowed' does not allow you to attach an entity 
//when an entity with the same key is already attached
//so we need to check for deleted entities and undelete them
var queryOptions = manager.queryOptions.using({
    includeDeleted: true,
    fetchStrategy: breeze.FetchStrategy.FromLocalCache
});

var existing = EntityQuery
    .from('ActualAnswers')
    .where('AnsweredQuestionID', '==', this.ID)
    .where('AnswerID', '==', answerid)
    .using(queryOptions)
    .using(manager)
    .executeLocally();

if (existing.length > 0 && existing[0].entityAspect.entityState.isDeleted()) {
    //rejectChanges fixes navigation properties. setUnchanged doesn't
    existing[0].entityAspect.rejectChanges(); 
}
else {
    createEntity("ActualAnswer", {
        AnsweredQuestionID: this.ID,
        AnswerID: answerid
    });
}
0
votes

Why don't you just change the state to Modified instead?

function unDeleteEntity(entity) {
    var ea = entity.entityAspect;
    ea.setModified();
}