2

I have the following scenario:

I am using EF with Repository pattern and Unit Of Work from here

Then I extended my partial class and have created a Finder class which have GetAll and other methods. You can this see below:

enter image description here

Below you can see that I am using a unit of work class with repositories of all classes to get the instance from the generic repository:

enter image description here

protected Repository<Category> _CategoryRepository;
public Repository<Category> CategoryRepository
{
    get { return _CategoryRepository ?? (_CategoryRepository = new Repository<Category>(context)); }
}

So in this way I had different repositories and when getting an entity from db and updating it from a different context caused problems. So I used this method to use for context lifetime management. And it resolved that issue.

Now the problem I am facing is in the following code:

var cat = Instance.Category.GetSingle(c => c.CategoryID == 7);

var orignal = cat.CategoryName;

var expected = cat.CategoryName + " Test Catg Update";

cat.CategoryName = expected;

cat.Update(); //This doesn't actually update due to a validation in place (which is correct)

cat = Instance.Category.GetSingle(c => c.CategoryID == 7);

Assert.AreEqual(cat.CategoryName, expected);

When I use Update and I have some validators in it, and the Update fails (for example due to size of the string exceeds 15 characters). When I try to call GetSingle (2nd last line of above code) again, it brings me the same old record which is [cat.CategoryName + " Test Catg Update"]. Is this a normal way? If not how can this be fixed so I can reload the object from database.

Let me know if you need any other code or reference.

2
  • Funny how many different views there are about EF & these two patterns. The tooltip from DbContext says it's implementing them both, and some blogs consider rewrapping it into another implementation is just additional complexity. I wonder if there's a single right way of going about it. ...feel free to remove the EF tag from your question title, the tag already categorizes your question under "EF". Commented Aug 17, 2013 at 18:42
  • Yes you are right about this, I have been looking into many different things and different ways of doing, thanks for pointing out the EF title... Commented Aug 17, 2013 at 19:14

1 Answer 1

1

in your Update() method, if the validation fails, simply set the state of the entity to EntityState.Unchanged. Under the covers, changing the state of an entity from Modified to Unchanged first sets the values of all properties to the original values that were read from the database when it was queried, and then marks the entity as Unchanged. This will also reject changes to FK relationships since the original value of the FK will be restored.

You may be able to take advantage of the ObjectContext.Refresh() method to handle this as well. However, this is on the ObjectContext, so you would need a method to handle it in your UoW. The refresh method would be something like context.Refresh(RefreshMode.ServerWins, entity);

Sign up to request clarification or add additional context in comments.

2 Comments

hi @andrew-counts, there is one more thing which I didn't realize, I am using fluent validation in that, and when update fails, a property returns the list of errors in the object, but while we set the object state to Unchanged and all values are restored, this property wont return the list of errors anymore...
@MuhammadUmair I'm not sure you can have it both ways with this. In order for you to show validation failures, you have to have a change that failed, and this assumes the failed change is still presented to the user allowing them to correct it. if you are really wanting to present the failure message and reset the object state both, you'll probably need to make some sort of reset() method on your UoW that can take the changed item and reset the EntityState after the validation has already been processed. I'm going to update the answer with another possible suggestion.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.