gpt4 book ai didi

entity-framework-4.1 - Entity Framework 4.1 更新外键属性时出现问题

转载 作者:行者123 更新时间:2023-12-01 04:09:30 30 4
gpt4 key购买 nike

我正在断开连接的环境中使用带有 DbContext API 的 Entity Framework 4.1 开发应用程序。我有两个基本实体,人员和学位。学位与人具有非强制性的一对多关系。

当我将 Person 实体上的 degreeId 属性更新为不同的值时,就会出现问题。当我保存更改时,EF 会在实际的 degree 表上生成一个 Update 语句。当两个或更多用户正在使用该应用程序时,这反过来会导致并发错误冲突。我在使用 SQL Profiler 时发现了这个问题。我已经使用 Fluent API 尝试了几种配置变体,但似乎没有任何东西可以抑制 degree 表上的附加 Update 语句。

这是我的实体:

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; }
}

在我的 Repository 类中,我正在加载 Person 对象图,如下所示:
public override Person GetById(int id)
{
return DataContext.People
.Include(d => d.Degree)
.FirstOrDefault(x => x.PersonId == id);
}

在我的服务层中,我正在获取人员记录,然后将 degreeId 属性更新为特定值。注意:UnitOfWork.Commit 方法在 DbContext 上公开 SaveChanges。
using (var unitOfWork = IoC.Resolve<IUnitOfWork>())
{
var personRepository = new PersonRepository(unitOfWork);
var person = personRepository.GetById(240);
person.DegreeId = 1;
personRepository.Update(person);
unitOfWork.Commit();
}

我的存储库更新方法附加了个人实体并将实体状态标记为已修改:
var state = DataContext.Entry(entity).State;
dbSet.Attach(entity);
DataContext.Entry(entity).State = EntityState.Modified;

这是在 Profiler session 中找到的 SQL 语句:
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

有谁知道如何阻止 EF 将此更新语句发送到 SQL Server?我的实体配置中是否有明显的东西导致 EF 假设学位也受到影响?

谢谢你。

最佳答案

我能够找到这个问题的原因并防止它发生,但我无法真正解释它为什么会发生。

我的表在我的实体的基类中包含一个 TimeStamp 列和一个相应的属性。
我没有在我的原始问题中显示基类,因为它只包含 RowVersion 和其他我认为不相关的审计属性。
有人会认为我会通过不假设任何关于 Entity Framework 的知识来学习。

这是我对学位实体的基类定义:

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; }
}

这是我的学位实体的上下文模型配置:
internal class DegreeConfiguration : EntityTypeConfiguration<Degree>
{
internal DegreeConfiguration()
: base()
{
ToTable("Degree", "dbo");
Property(x => x.RowVersion).IsRowVersion();
}
}

由于我的应用程序要求,我必须使用 Include 方法加载 Person 实体以急切加载度实体,因此对象图是
当消费者请求实体时完全填充。
return ctx.People.Include(p => p.Degree).Where(x => x.PersonId == id).First();

当Person对象的DegreeId属性被修改并附加到Context时,生成如下Update语句
调用 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

即使我没有故意更新学位实体并在两个或更多用户同时使用该应用程序时造成严重破坏,也会发生这种情况。

为了禁止在 degree 导航属性上生成 Update 语句,我注释掉了模型配置的并发检查,如下所示:
internal class DegreeConfiguration : EntityTypeConfiguration<Degree>
{
internal DegreeConfiguration()
: base()
{
ToTable("Degree", "dbo");
//Property(x => x.RowVersion).IsRowVersion();
}
}

重新执行该过程后,EF 不再生成有问题的 Update 语句。

我已经在 MS 站点上对 EF 4.1 以及一般的 Google 搜索进行了大量搜索。我想不出任何具体的解释。

谢谢你。

关于entity-framework-4.1 - Entity Framework 4.1 更新外键属性时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7178978/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com