EF:使用延迟加载的必需属性时验证失败 [英] EF: Validation failing on update when using lazy-loaded, required properties

查看:97
本文介绍了EF:使用延迟加载的必需属性时验证失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  public class MyContext:BaseContext 
{
public DbSet< FOO> Fo子组; }
public DbSet< Bar>酒吧{get;组; }
}

public class Foo
{
public int Id {get;组; }
public int Data {get;组; }
[必需]
public virtual Bar Bar {get;组; }
}

public class Bar
{
public int Id {get;组;
}

以下程序失败:

  object id; 
using(var context = new MyContext())
{
var foo = new Foo {Bar = new Bar()};
context.Foos.Add(foo);
context.SaveChanges();
id = foo.Id;
}
using(var context = new MyContext())
{
var foo = context.Foos.Find(id);
foo.Data = 2;
context.SaveChanges(); // Crash here
}

使用 DbEntityValidationException EntityValidationErrors 中的消息是栏栏是必需的。



但是,如果我通过在 SaveChanges 之前添加以下行来强制加载 Bar 属性:

  var bar = foo.Bar; 

一切正常。如果我删除了 [Required] 属性,这也是有效的。



这是真的预期的行为吗?有没有任何解决方法(除了每次要更新一个实体加载每一个所需的参考)

解决方案

我发现了以下帖子有同样问题的答案: / p>


这个问题的原因是在
RC和RTM验证不再懒惰
加载任何属性。这个
更改的原因是因为当
a保存
很多实体有
懒惰加载属性验证
将逐个获得一个可能
导致一个很多意外的
交易和瘫痪的
表现。



解决方法是在保存
之前显式加载
所有验证的属性或通过使用.Include()验证,您可以在
上阅读更多关于如何做到这一点:$ b​​ $ b http://blogs.msdn.com/b/adonet/archive/2011/01/ 31 / using-dbcontext-in-ef-feature-ctp5-part-6-loading-related-entities.aspx




<我认为这是一个非常糟糕的代理实现。虽然不必要地走对象图并且重新启动延迟加载的属性当然是要避免的(但是在微软的首例EF中显然被忽略),您不需要去取消代理一个包装器来验证它是否存在。在第二个想法,我不知道为什么你需要走对象图反正,ORM的变化跟踪器肯定知道什么对象需要验证。



我不知道为什么问题存在,但我确定如果我使用说NHibernate,我不会有这个问题。



我的'解决方法' - 我所做的是定义EntityTypeConfiguration类中所需的关系属性,并删除了Required属性。这应该使它工作正常。这意味着您不会验证关系,但会更新失败。不是理想的结果。


Given this extremely simple model:

public class MyContext : BaseContext
{
    public DbSet<Foo> Foos { get; set; }
    public DbSet<Bar> Bars { get; set; }
}

public class Foo
{
    public int Id { get; set; }
    public int Data { get; set; }
    [Required]
    public virtual Bar Bar { get; set; }
}

public class Bar
{
    public int Id { get; set; }
}

The following program fails:

object id;
using (var context = new MyContext())
{
    var foo = new Foo { Bar = new Bar() };
    context.Foos.Add(foo);
    context.SaveChanges();
    id = foo.Id;
}
using (var context = new MyContext())
{
    var foo = context.Foos.Find(id);
    foo.Data = 2;
    context.SaveChanges(); //Crash here
}

With a DbEntityValidationException. The message found in EntityValidationErrors is The Bar field is required..

However, if I force loading of the Bar property by adding the following line before SaveChanges:

var bar = foo.Bar;

Everything works fine. This also works if I remove the [Required] attribute.

Is this really the expected behavior? Are there any workarounds (besides loading every single required reference every time I want to update an entity)

解决方案

I found the following post that had an answer for the same problem:

The cause of this problem is that in RC and RTM validation no longer lazy loads any properties. The reason this change was made is because when saving a lot of entities at once that have lazy loaded properties validation would get them one by one potentially causing a lot of unexpected transactions and crippling performance.

The workaround is to explicitly load all validated properties before saving or validating by using .Include(), you can read more on how to do this here: http://blogs.msdn.com/b/adonet/archive/2011/01/31/using-dbcontext-in-ef-feature-ctp5-part-6-loading-related-entities.aspx

My take on this is that is a pretty crappy proxy implementation. While unnecesarily walking the object graph and retriveing lazy-loaded properties is naturally something to be avoided (but apparently overlooked in Microsoft's first incarnation of EF), you shouldn't have to need to go un-proxying a wrapper to validate that it exists. On second thoughts, I'm not sure why you need to go walking the object graph anyway, surely the change tracker of the ORM knows what objects require validation.

I'm not sure why the problem exists, but I'm sure I wouldn't be having this problem if I was using say, NHibernate.

My 'workaround' - What I've done is define the Required nature of the relationship in a EntityTypeConfiguration class, and removed the Required attribute. This should make it work fine. It means that you will not validate the relationship, but it will fail the update. Not an ideal result.

这篇关于EF:使用延迟加载的必需属性时验证失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆