문제

For example. There is a class named A.

public class A
{
    [Key]
    [Required]
    public virtual Guid Id {get;set;}
    [Required]
    public virtual string Name {get;set;}
    [Required]
    public virtual B B {get;set;}
}

When I call this method it will throw exception that B can not be null.

public void Edit(Guid id, string name)
{
    A a = _DbSet.Find(id);
    a.Name = name;
    _DbContext.SaveChanges();
}

But this will success.

public void Edit(Guid id, string name)
{
    A a = _DbSet.Find(id);
    a.Name = name;
    B b = a.B; 
    _DbContext.SaveChanges();
}

Is this a bug of Entity Framework?

I use it with the version 6.1.

====================================

I found a regular that if a property link to a entity and it doesn't load from database then it will throw exception when you call SaveChanges()

도움이 되었습니까?

해결책 2

I check the source code of Entity Framework. I found that the reason of bug is about Validate method of ValidationAttributeValidator class of EF assembly.

This method is call when a entity going to validate. And it will check any Attribute of Property. However, RequiredAttribute is not belong to EF assembly. GetValidationResult method of RequiredAttribute will not care about lazy loading of EF.

So, I think the solution is change the code of Validate method of ValidationAttributeValidator class. Ignore it if Attribute is RequiredAttribute and do something to validate property with lazy loading.

다른 팁

It's not a bug - it's a feature! You have specified B as Required but also virtual, which means it will be lazy loaded - in other words, it won't be loaded until you reference it.

So in your first example, you never load in B, so you get the exception. In the second example, you do reference B, which incidentally means another call to the database, and it gets loaded in.

You need to call Include to eager load B. Unfortunately, you can't use Include with Find, so try this instead:

A a = _DbSet.Include("B").SingleOrDefault(a => a.id == id);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top