实体框架DbContext.SaveChanges()返回比我预期多一个int

本文关键字:int 一个 DbContext 框架 SaveChanges 返回 实体 | 更新日期: 2023-09-27 18:07:44

我正在尝试调试,或者找出实体框架在我的插入期间在这里做什么。这是我的作业上下文模型生成器,我在其中处理作业、日志和用户实体

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new JobMap());
        modelBuilder.Configurations.Add(new LogMap());
        modelBuilder.Configurations.Add(new UserMap());
        this.Configuration.LazyLoadingEnabled = false;
        base.OnModelCreating(modelBuilder);
    }
下面的

My Job实体有两个指向其他实体的导航属性。但是,User和Log类没有返回作业的导航属性,因为这在我的程序中没有意义,即使它们在DB中设置(并且用户没有返回日志的导航)

public class Job: BaseEntity
{
    // ... other properties of type string, int, DateTime etc.
    public int UserId { get; set }
    public User Owner { get; set; }
    public ICollection<Log> Logs{ get; private set; }
}

public class Log: BaseEntity
{
    // ... other properties of type string, int, DateTime etc.
    public int UserId { get; set }
    public User Owner { get; set; }
}

在我的映射类中,作业类是唯一具有fluent API中定义的关系的类。日志和用户类没有建立关系。

    public JobMap()
    {
        // .. table and column mappings here
        // Relationships
        this.HasRequired(t => t.Owner)
        this.HasMany(t => t.Logs)
            .WithRequired()
            .Map(t => t.MapKey("JobId"));
    }

当我去创建一个新的作业时,我特别向作业类添加一个日志和用户,并调用作业实体的通用存储库。

    public T InsertOrUpdate<T>(T entity) where T : BaseEntity
    {
        if (entity.Id == default(int))
        {
            this.Entry<T>(entity).State = EntityState.Added;
        }
        else
        {
            this.Set<T>().Add(entity);
            this.Entry<T>(entity).State = StateMapper.ConvertState(entity.State);
        }
        return entity;
    }

当我调用DbContext.SaveChanges时,我检查ChangeTracker,作业被标记为已添加,日志被标记为已添加,用户被标记为未更改(因为用户存在),但是,SaveChanges返回3,而不是像我期望的那样返回2。我的设置有什么问题吗?甚至查看SQL profiler,我看到两个插入查询

exec sp_executesql N'INSERT [dbo].[Job]([UserId], [RequestDateTime], [DueDate],[Reason]    VALUES (@0, @1, @2, @3)
SELECT [JobId]
FROM [dbo].[Job]
WHERE @@ROWCOUNT > 0 AND [JobId] = scope_identity()',N'@0 nvarchar(20),@1 datetime2(7),@2 datetime2(7),@3 nvarchar(10)',@0=N'C123',@1='2014-06-07 09:28:00.7538457',@2='2014-06-14 00:00:00',@3=N'klj''
exec sp_executesql N'INSERT [dbo].[Log]([ChangedByUserId], [ChangedDateTime], [Reason] , [JobId])
VALUES (@0, @1, @2, @3)
SELECT [LogId]
FROM [dbo].[Log]
WHERE @@ROWCOUNT > 0 AND [LogId] = scope_identity()',N'@0 nvarchar(20),@1 datetime2(7),@2 nvarchar(200),@3 int',@0=N'C123',@1='2014-06-07 09:28:00.7538457',@2=N'Job Created',@3=128

编辑

即使user设置为Null,也会执行这两个查询并返回3,所以我的设置中一定有问题。如果用户被设置为已添加状态,那么SaveChanges返回4?

实体框架DbContext.SaveChanges()返回比我预期多一个int

我不是实体框架方面的专家,但我想把我的发现发布出来,以防这绊倒了其他人。这行代码使得SaveChanges()每次都比我预期的多返回一个int

this.HasMany(t => t.Logs)
    .WithRequired()
    .Map(t => t.MapKey("JobId"));

我删除了这个映射,并在日志类中放置了一个外键,SaveChanges()返回了我期望的数字。所以这个特定的映射一定对关系做了一些额外的事情我现在还不确定