I'm using Entity Framework 6 Code First to model a user/session relationship:
My entities look like this (I've removed everything but those properties relating to my problem):
class User
{
public int Id { get; set; }
[ForeignKey("CurrentSession")]
public int? CurrentSessionId { get; set; }
public virtual Session CurrentSession { get; set; }
[InverseProperty("User")]
public virtual ICollection<Session> Sessions { get; set; }
}
class Session
{
public int Id { get; set; }
public int UserId { get; set; }
public virtual User User { get; set; }
public string X { get; set; }
}
This creates the appropriate foreign key relationships in the database (optional FK from User to Session on CurrentSessionId column; required FK from Session to User on UserId column) so I'm happy with that.
What I'm trying to do is load a user and its current session, change a property value on the CurrentSession
( X
in this example), remove the relationship between the user and the session (think: "user's session is no longer current"), then save both changes as a single transaction (ie. a single call to SaveChanges
).
Unfortunately, whichever way I try to modify the entity properties it always results in the User
entity change being saved (SQL UPDATE
on User table) but not the Session
entity change. I could really do with this pair of updates being atomic. Is there any way of doing that or must I be forced to perform two separate SaveChanges
calls?
Thus far I've tried this:
user.CurrentSession.X = ...;
user.CurrentSession = null;
dbContext.SaveChanges();
and this:
user.Sessions.Add(user.CurrentSession);
user.CurrentSession.X = ...;
user.CurrentSession = null;
dbContext.SaveChanges();
and this:
Session currentSession = user.CurrentSession;
user.CurrentSession = null;
currentSession.X = ...;
dbContext.Sessions.Attach(currentSession);
dbContext.Entry(currentSession).State = EntityState.Modified;
dbContext.SaveChanges();
But as soon as I set CurrentSession
to null
, EF effectively 'loses' the changes I make to the session entity.
It's okay, it does seem to work after all, even the simplest first code example.
The thing that threw me was that I have a basic DbCommandInterceptor
class running that is just echoing the SQL statements to the debug console, and this only shows a single SQL UPDATE
command despite two different tables being updated. I'm not sure why that's happening. Here's the code for the interceptor:
class DummyInterceptor : DbCommandInterceptor
{
public override void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
base.ReaderExecuting(command, interceptionContext);
Debug.WriteLine(new string('=', 70));
Debug.WriteLine(command.CommandText);
}
}
Thinking about it now, maybe it's because I'm only overriding the ReaderExecuting
method? Need to check that out later.
Yes, that was what it was. I overrided (overrode?) the ScalarExecuting
and NonQueryExecuting
methods and then I saw the other SQL UPDATE
query. The reason the two were in different 'groups' was because the User table has a rowversion
column on it, and EF was getting the new row version after performing the FK update.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.