DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Comprehensive Guide to Property-Based Testing in Go: Principles and Implementation
  • Implement Hibernate Second-Level Cache With NCache
  • Modify JSON Data in Postgres and Hibernate 6
  • Top 10 C# Keywords and Features

Trending

  • How to Submit a Post to DZone
  • Give Your AI Assistant Long-Term Memory With perag
  • AI Assessments Are Everywhere
  • From "Vibe Coding" to Production: Setting Up an Evals Loop for Claude Agents
  1. DZone
  2. Coding
  3. Frameworks
  4. Entity Framework - Update Single Property (Partial Update)

Entity Framework - Update Single Property (Partial Update)

By 
Mihai Huluta user avatar
Mihai Huluta
·
May. 28, 13 · Interview
Likes (1)
Comment
Save
Tweet
Share
22.7K Views

Join the DZone community and get the full member experience.

Join For Free

Have you ever tried to update specific fields of an entity using Entity Framework? If yes, then I can assume that System.Data.Entity.Validation.DbEntityValidationResult – Validation failed for one or more entities. See ‘EntityValidationErrors’ property for more details. Exception is not something new to you. 

While working recently on a project for which I was using Entity Framework 5.x CF (the part with code first is not relevant) I bumped into an interesting piece of code. The main idea behind it is to perform updates for a single property and ignore the rest even if they don't respect the constraints defined in the model. Please note that I have found PartialEntityValidation class somewhere on the internet and unfortunately I do not remember where, I was not able to find it again. The only changes made by me are related to code formatting. I will present the code first and explain the logic behind it afterwards.

using System.Collections.Generic;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Validation;

namespace MyProject.Data.Contexts.Concrete
{
    public class PartialEntityValidation
    {
        private readonly IDictionary<DbEntityEntry, string[]> _store;

        public PartialEntityValidation()
        {
            _store = new Dictionary<DbEntityEntry, string[]>();
        }

        public void Register(DbEntityEntry entry, string[] properties)
        {
            if (_store.ContainsKey(entry))
                _store[entry] = properties;
            else
                _store.Add(entry, properties);
        }

        public void Unregister(DbEntityEntry entry)
        {
            _store.Remove(entry);
        }
        public bool IsResponsibleFor(DbEntityEntry entry)
        {
            return _store.ContainsKey(entry);
        }
        public void Validate(DbEntityValidationResult validationResult)
        {
            var entry = validationResult.Entry;
            foreach (var property in _store[entry])
            {
                var validationErrors = entry.Property(property).GetValidationErrors();
                foreach (var validationError in validationErrors)
                    validationResult.ValidationErrors.Add(validationError);
            }
        }
    }
}
PartialEntityValidation class has a simple constructor which initializes a new dictionary store where the key of it is an DbEntityEntry and the value (currently) an empty string array. The string array will hold later on the properties which should be validated. The  class has four methods: Register, Unregister, IsResponsibleFor and Validate. Now let me explain a bit what each method does. Register adds a new DbEntityEntry with the properties that have to be validated to the existing store. It basically registers a new entity entry for validation. It is quite obvious what Unregister method does; it removes an entity entry from the existing store. IsResponsibleFor method determines if an entity entry is present in the existing store and if it will be part of the validation process. The last method is Validate which accepts a single parameter of DbEntityValidationResult type, from which it takes the entity entry associated with the validation result and validates each property of the entity entry present in the store. If there are any validation errors those are added on ValidationErrors collection of the validation result.

Now it is time to see how to use PartialEntityValidation class. In My case I have exposed it as a public read only property of the context and had ValidateEntity method overridden  at context level.

using System;   
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Validation;

namespace MyProject.Data.Contexts.Concrete
{
    public class MyContext : DbContext
    {
        private readonly PartialEntityValidation _partialEntityValidation;

        static MyContext()
        {
            Database.SetInitializer<T>(null);
        }

        protected MyContext()
            : base("MyDb")
        {
            _partialEntityValidation = new PartialEntityValidation();
            Configuration.LazyLoadingEnabled = false;
        }

        public PartialEntityValidation PartialValidation { get { return _partialEntityValidation; } }

        protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items)
        {
            if (PartialValidation.IsResponsibleFor(entityEntry))
            {
                var validationResult = new DbEntityValidationResult(entityEntry, new List<DbValidationError>());
                PartialValidation.Validate(validationResult);

                return validationResult;
            }

            return base.ValidateEntity(entityEntry, items);
        }
    }
}
I am sure that I do not have to explain the logic behind ValidateEntity method from the db context. The final piece is the repository where the partial update is  invoked.

using System;
using System.Linq;
using System.Linq.Expressions;

namespace MyProject.Data.Repositories.Concrete
{
    public class MyRepository
    {
		private readonly MyContext _context;
	
        public MyRepository(MyContext context)
        {
			_context = context;
		}

        public void DeleteProduct(Guid productId)
        {
            var product = new Product { ProductId = productId, IsDeleted = true };
            _context.PartialValidation.Register(_context.Entry(product), new[] { "IsDeleted" });
            Update<Product>(workspace, p => p.IsDeleted);
            _context.SaveChanges();
            ((IObjectContextAdapter)_context).ObjectContext.Detach(product);
        }
		
		public void Update<T>(T entity, Expression<Func<T, object>> property) where T : class
        {
            var  entry = _context.Entry(entity);
            _context.Set<T>().Attach(entity);
            entry.Property(property).IsModified = true;
        }
    }
}
Please take into consideration that this is a demo repository which doesn't do much at all except to present  how a partial update is performed. The repository has two important methods. First one is DeleteProduct which performs a soft delete by updating "IsDeleted" property of product entity to true. This is achieved by creating a new product object of which primary key is "ProductId" with "IsDeleted" property set to true. The next step is to register the entity entry along with the "IsDeleted" property (this is the only property we want to have it updated, all other properties of Product entity will be ignored) into PartialValidation store. Update method is called which attaches the entity entry to the context and marks it as modified in order to have it updated by entity framework. That is all, I really hope that you got the idea behind this even if I did not provided an actual sample application for download.
Entity Framework Property (programming)

Opinions expressed by DZone contributors are their own.

Related

  • Comprehensive Guide to Property-Based Testing in Go: Principles and Implementation
  • Implement Hibernate Second-Level Cache With NCache
  • Modify JSON Data in Postgres and Hibernate 6
  • Top 10 C# Keywords and Features

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook