有人遇到以下内容吗?用指称其他实体的字段验证对象会给您带来一个错误,说明该字段不存在,并且当您调试程序时,您将检查字段的实体 人口稠密。

这已经发生了两次,我已经发生了两次,懒惰负载似乎有些问题,好像懒惰的负载没有足够快地给答案。

我们有这个(简化的)模型

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分的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]的验证验证者 Questions 经过调试器检查,确实包含了与 IdS 4和5。如果我暂停调试器 if- 陈述验证将在之后正确进行。

奇怪的是,我以前没有(故意)遇到这些错误,也没有更新任何库或数据库软件。

这种情况使我有些恐惧,因为我似乎不能依靠懒惰的加载来始终工作。也许我做错了什么?

这感觉与 EF 4.1加载过滤的儿童收集不适用于多个人 但是我无法解释这将如何适用。

Update1:通过按照第一个示例中提供的步骤来弹出以下例外:

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 是一个包含客户端的DATA的对象。 survey.CanAdministrate(Context) 使用上下文读取来自DB的整个组织原子树以确定角色。

有帮助吗?

解决方案

这是设计,恕我直言,这是非常好的功能。上下文内部关闭某些操作中的懒惰加载,验证是其中之一。这是导致该方法的内部实施的一部分:

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

为什么好吗?因为如果您不想要它们,它会避免泄漏的懒惰负载。顺便提一句。如果您将验证逻辑放在不必加载的属性上,则您做错了。您有责任确保在验证之前填写所有必要的属性。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top