Entity Framework 4.1 Problems updating foreign key properties

I am working on an application using Entity Framework 4.1 with the DbContext API in a disconnected environment. I have two main personalities: Personality and Degree. The degree has an optional one-to-many relationship with Man.

The problem occurs when I update the DegreeId property of the Person object to a different value. When I save the changes, EF generates an Update statement in the actual Degree table. This, in turn, causes a concurrency error violation when two or more users use the application. I was able to find a problem when using SQL Profiler. Ive tried several configuration options using the Fluent API, but nothing seems to suppress the optional Update statement in the Degree table.

Here are my entities:

public partial class Person { public int PersonId { get; set; } public string FirstName { get; set; } public string MiddleName { get; set; } public string LastName { get; set; } public Nullable<int> DegreeId { get; set; } public Degree Degree { get; set; } } public partial class Degree { public int DegreeId { get; set; } public string Name { get; set; } } 

In my Repository class, I load the Person object graph as such:

 public override Person GetById(int id) { return DataContext.People .Include(d => d.Degree) .FirstOrDefault(x => x.PersonId == id); } 

At my service level, I get a person record and then update the DegreeId property to a specific value. Note. The UnitOfWork.Commit method provides SaveChanges in the DbContext.

 using (var unitOfWork = IoC.Resolve<IUnitOfWork>()) { var personRepository = new PersonRepository(unitOfWork); var person = personRepository.GetById(240); person.DegreeId = 1; personRepository.Update(person); unitOfWork.Commit(); } 

My repository update method attaches the user object and marks the state of the object as changed:

 var state = DataContext.Entry(entity).State; dbSet.Attach(entity); DataContext.Entry(entity).State = EntityState.Modified; 

Here is the SQL statement found in the Profiler session:

 exec sp_executesql N'declare @p int update [Client].[Degree] set @p = 0 where (([DegreeId] = @0) and ([RowVersion] = @1)) select [RowVersion] from [Client].[Degree] where @@ROWCOUNT > 0 and [DegreeId] = @0',N'@0 int, @1 binary(8)',@0=1,@1=0x0000000000004469 

Does anyone know how to stop EF from sending this update statement to SQL Server? Is there something obvious in my entity configuration that makes EF accept Degree is also affected?

Thanks.

+4
source share
1 answer

I managed to find the cause of this problem and prevent its occurrence, but I can not explain why this is happening.

My tables include the TimeStamp column and the corresponding property in the base class for my objects. I did not show the base class in my original question, because it includes only RowVersion and other audit properties, which I thought were irrelevant. It would seem that I would know, I do not know anything about the Entity Framework.

Here is the base class definition for the Degree object:

 public abstract class EntityBase : ValidableObject, IEntityBase { public virtual byte[] RowVersion { get; protected set; } public virtual DateTime? CreateDate { get; set; } public virtual string CreateUser { get; set; } public virtual DateTime? ModifyDate { get; set; } public virtual string ModifyUser { get; set; } } 

Here is my context model configuration for a Degree object:

 internal class DegreeConfiguration : EntityTypeConfiguration<Degree> { internal DegreeConfiguration() : base() { ToTable("Degree", "dbo"); Property(x => x.RowVersion).IsRowVersion(); } } 

Due to the requirements of my application, I have to load the Person object using the Include method so that I can load the Degree object eagerly so that the graph of the object is completely filled when the consumer requests the object.

 return ctx.People.Include(p => p.Degree).Where(x => x.PersonId == id).First(); 

When the DegreeId property of the Person object is changed and bound to the Context, the following Update statement is created after calling SaveChanges ():

 exec sp_executesql N'declare @p int update [dbo].[Degree] set @p = 0 where (([DegreeId] = @0) and ([RowVersion] = @1)) select [RowVersion] from [dbo].[Degree] where @@ROWCOUNT > 0 and [DegreeId] = @0',N'@0 int, @1 binary(8)',@0=2,@1=0x00000000000007DF 

This happens despite the fact that I am not consciously updating the Degree object and cause chaos when two or more users use the application at the same time.

To suppress the Update statement from the generated property of the Degree property, I commented out the concurrency check of the model configuration as such:

 internal class DegreeConfiguration : EntityTypeConfiguration<Degree> { internal DegreeConfiguration() : base() { ToTable("Degree", "dbo"); //Property(x => x.RowVersion).IsRowVersion(); } } 

After executing the process again, EF no longer generates the problematic Update statement.

I conducted a significant number of searches both on the MS website for EF 4.1, and in a regular Google search. I cannot come up with any concrete explanation.

Thanks.

+2
source

All Articles