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
Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
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

Integrating PostgreSQL Databases with ANF: Join this workshop to learn how to create a PostgreSQL server using Instaclustr’s managed service

Mobile Database Essentials: Assess data needs, storage requirements, and more when leveraging databases for cloud and edge applications.

Monitoring and Observability for LLMs: Datadog and Google Cloud discuss how to achieve optimal AI model performance.

Automated Testing: The latest on architecture, TDD, and the benefits of AI and low-code tools.

Related

  • Ensuring Reliable Microservice Deployment With Spring Boot Build Info Maven Plugin
  • New ORM Framework for Kotlin
  • Angular Component Tree With Tables in the Leaves and a Flexible JPA Criteria Backend
  • Practical Example of Using CSS Layer

Trending

  • Multi-Tenancy With Keycloak, Angular, and SpringBoot
  • Running End-To-End Tests in GitHub Actions
  • TDD With FastAPI Is Easy
  • The Stairway to Apache Kafka® Tiered Storage
  1. DZone
  2. Coding
  3. Frameworks
  4. Entity Framework - Update Single Property (Partial Update)

Entity Framework - Update Single Property (Partial Update)

Mihai Huluta user avatar by
Mihai Huluta
·
May. 28, 13 · Interview
Like (1)
Save
Tweet
Share
21.29K 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

  • Ensuring Reliable Microservice Deployment With Spring Boot Build Info Maven Plugin
  • New ORM Framework for Kotlin
  • Angular Component Tree With Tables in the Leaves and a Flexible JPA Criteria Backend
  • Practical Example of Using CSS Layer

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • 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: