延迟/延迟加载链接不及时?

时间:2011-09-05 07:43:05

标签: c# entity-framework asp.net-mvc-3 entity-framework-4.1

有人遇到以下情况吗?使用引用其他实体的字段验证对象会引发错误,指出该字段不存在,并且当您调试程序时,您将检查实体 填充的字段。< / p>

现在两次发生这种事情,似乎是延迟加载的一些问题,好像延迟加载没有给出足够快的答案。

我们有这个(简化)模型

class Survey {
  ...
  public bool Enabled {get; set;}
  [Required]
  public virtual OrganisationalUnit OU {get; set;}
  ...
}

如果我们只执行Context.Surveys.Single(id)Context.Surveys.Where(s => s.Id == id),更改Enabled字段(或任何其他字段),并执行Context.SaveChanges(),则会在9时间抛出一个验证错误,即OU字段是必需的,并且它不存在。

添加.Include(s => s.OU)后,这个问题就解决了,我认为这就是它的结束。虽然昨天我再次遇到类似的问题,但代码如下:

public class SurveyQuestionMultipleChoiceMultiSelect : SurveyQuestionMultipleChoice
{
    public override IEnumerable<ValidationResult> validateValue(string _, IEnumerable<string> values)
    {
        int ivalue;
        foreach( string value in values) {

            bool success = int.TryParse(value, out ivalue);

            if (!success || !Questions.Any(q => q.Id == ivalue))
                yield return new ValidationResult(String.Format(GUI.error_multiplechoice_answer_not_element_of, ivalue));
        }
    }
}

这将返回值[4,5]的ValidationErrors,而Questions通过调试器检查时确实包含Id s 4和5的问题。如果我暂停调试器{ {1}} - 声明验证将在之后正确进行。

奇怪的是,我之前没有(明知)遇到过这些错误,而且我没有更新任何库或数据库软件。

这种情况让我感到害怕,因为我似乎不能依赖Lazy Loading来始终工作。或者也许我做错了什么?

这与EF 4.1 loading filtered child collections not working for many-to-many松散相关,但我无法解释这在这里是如何适用的。

UPDATE1 : 按照第一个示例中提供的步骤弹出以下异常:

if

实现此目的的代码(不是由我个人编写,而是由另一个团队成员编写):

System.Data.Entity.Validation.DbEntityValidationException was unhandled by user code
  Message=Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
  Source=EntityFramework
  StackTrace:
       at System.Data.Entity.Internal.InternalContext.SaveChanges()
       at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
       at System.Data.Entity.DbContext.SaveChanges()
       at Caracal.Application.Controllers.SurveyController.BulkEnable(SurveyBulkAction data) in C:\Users\Alessandro\Caracal\DigEvalProject\trunk\Caracal\application\Controllers\SurveyController.cs:line 353
       at lambda_method(Closure , ControllerBase , Object[] )
       at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
       at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
       at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
       at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12()
       at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
  InnerException: 
    <really-empty>

bool option = data.option == "true"; // Check if all surveys can be set to the enabled state foreach (int id in data.surveys) { Survey survey = Context.Surveys.SingleOrDefault(s => s.Id == id); if (survey == null || !survey.CanAdministrate(Context)) return JsonResponse.Error(GUI.survey_enable_change_bulk_failed); surveys.Add(survey); } // Enable/disable the selected surveys. foreach (Survey survey in surveys) survey.Enabled = option; Context.SaveChanges(); 是一个包含来自客户端的后期数据的对象。 data使用Context从DB中读取整个OrganisationalUnits树以确定角色。

1 个答案:

答案 0 :(得分:3)

这是设计和恕我直言,这是非常好的功能。 Context在内部关闭某些操作中的延迟加载,验证就是其中之一。这是导致它的方法的内部实现的一部分:

public virtual DbEntityValidationResult GetValidationResult(IDictionary<object, object> items)
{
    EntityValidator entityValidator = 
        this.InternalContext.ValidationProvider.GetEntityValidator(this);
    bool lazyLoadingEnabled = this.InternalContext.LazyLoadingEnabled;
    this.InternalContext.LazyLoadingEnabled = false;
    DbEntityValidationResult result = null;
    try
    {
        ...
    }
    finally
    {
        this.InternalContext.LazyLoadingEnabled = lazyLoadingEnabled;
    }
    return result;
}

为什么好?因为它可以避免在您不需要它们时泄漏延迟负载。顺便说一句。如果您将验证逻辑放在不必加载的属性上,那么您就错了。您有责任确保在验证之前填写所有必要的属性。

相关问题