0

首先,我不是实体框架方面的专家。

而且我在一个项目的存储库中看到了一些代码,其中

  • 将实体上的 EntityReference 属性设为 NULL
  • 并保留 EntityReference 的 ID

在保存此实体的更改之前。

例如,它在保存 Foo 实体之前执行此设置:

if (foo.Bar !=null)
{
  foo.BarID = foo.Bar.ID;
  foo.Bar = null;
}

这可以是 EntityFramework 相关的要求,以使 EntityReference 属性为空,但仅使用它们的 ID 来保存?

4

2 回答 2

1

应该编写该代码以防止数据库更改为Bar实体。

看这个例子:

var foo = db.Foo.Include("Bar").First() // get some foo from db
foo.SomeColumn = "i have changed!";
var barId = foo.BarID; // get the "bar" id

foo.Bar.SomeColumn = "i have changed!"; // this will change the values from this column
db.SaveChanges(); // i will save changes from "bar" and from "foo", becouse "bar" was attached on get

在该代码中,您更改了两个实体的值,也许您的代码正试图阻止这种情况。如果你不包括Bar它只是不更新​​。

于 2013-01-15T18:10:05.243 回答
1

不,通常这不是必需的。例如,当使用附加实体时,您可以更改 FK 属性或引用,两者都可以:

var foo = context.Foos.Include("Bar").Single(f => f.ID == 1);

然后...

foo.BarID = 5;
context.SaveChanges();

...会工作和...

var newBar = new Bar { ID = 5 };
context.Bars.Attach(newBar);
foo.Bar = newBar;
context.SaveChanges();

...也会起作用。无需取消引用。

如果您的问题中的代码可能有意义

  • foo-foo.Bar关系处于不一致/矛盾的状态
  • 你知道出了什么问题

例如:

var foo = new Foo { ID = 1 };

foo.BarID = 4;
foo.Bar = new Bar { ID = 5 };

repo.UpdateFoo(foo);

并且UpdateFoo是:

public void UpdateFoo(Foo foo)
{
    context.Foos.Attach(foo); // will throw an exception
    context.Entry(foo).State = EntityState.Modified;
    context.SaveChanges();
}

Attach行将引发异常,因为 FK 值为BarID4引用foo.Bar的是Barnumber 5。EF 不知道什么是有效的并且会拒绝写一个更新。

您现在可以通过将问题中的代码添加到UpdateFoo方法中来解决此问题:

public void UpdateFoo(Foo foo)
{
    if (foo.Bar !=null)
    {
        foo.BarID = foo.Bar.ID;
        foo.Bar = null; // this line is not really necessary
    }

    context.Foos.Attach(foo); // no  exception anymore
    context.Entry(foo).State = EntityState.Modified;
    context.SaveChanges();
}

但这依赖于foo.Bar(ID = 5)有效且foo.BarID(ID = 4)无效的假设。

通常这不一定是正确的,它可能只是相反的方式。在我看来,这个片段是一种代码异味,它试图修复存储库层中实际在另一层(业务层左右)中创建的不一致。

于 2013-01-15T18:55:11.780 回答