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
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

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

  • Intro to RAG: Foundations of Retrieval Augmented Generation, Part 2
  • Go 1.24+ Native FIPS Support for Easier Compliance
  • The Role of AI in Identity and Access Management for Organizations
  • Developers Beware: Slopsquatting and Vibe Coding Can Increase Risk of AI-Powered Attacks
  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.3K 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
Oops! Something Went Wrong

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

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

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 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!