懒惰/递延不按时链接加载? [英] Lazy / Deferred loading of links not on time?

查看:133
本文介绍了懒惰/递延不按时链接加载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是不是有人遇到以下?验证与域引用其他实体对象应该把你扔一个错误,指出该领域并不present并且当您将调试程序,你会检查这些字段是实体稀少。

Did someone experience the following? Validating objects with fields that refer to other Entities would throw you an error stating that the field wasn't present and that when you would debug the program and you would inspect the entities that the fields are populated.

这已经发生在我身上两次,它似乎有些问题,延迟加载,仿佛延迟加载并没有给出答案不够快。

This has happened to me on two occasions now and it seems to be some problem with lazy loading, as if the lazy loading did not give the answer fast enough.

我们有这个(简化)模型,其中

We have this (simplified) model where

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

如果我们只是做 Context.Surveys.Single(ID) Context.Surveys.Where(S = GT; s.Id = = ID),改变了已启用字段(或任何其他字段),并做了 Context.SaveChanges(),将在9个10倍抛出了字段是必须的一个验证错误,它不是present。

If we would just do Context.Surveys.Single(id) or Context.Surveys.Where(s => s.Id == id), changing the Enabled field (or any other field), and do a Context.SaveChanges() it would in 9 out of 10 times throw a validation error that the OU field is required and that it's not present.

后加入 .INCLUDE(S​​ = GT; s.OU)这个问题解决了,我想这是它的结束。虽然昨天我又遇到了类似的问题有以下code:

After adding .Include(s => s.OU) this problem was solved and I thought this was the end of it. Although yesterday again I encountered a similar problem with the following code:

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

这将返回ValidationErrors的值[4,5],而问题经检查通过调试器确实包含与标识问题第4和5。如果我会暂停调试器在瞬间如果语句来验证将通过正确算账。

This would return ValidationErrors for values [4,5] whilst Questions upon inspection through the debugger indeed contained questions with Ids 4 and 5. If I would pause the debugger a moment on the if-statement the validation would go through correctly afterwards.

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

The odd thing is that I didn't (knowingly) experience these errors before and that I didn't update any libraries or database software.

这情况我害怕了一下,因为它似乎我不能依靠延迟加载总是工作。或者,也许我做错了什么?

This situation frightens me a bit as it seems I cannot rely on Lazy Loading to always work. Or maybe I'm doing something wrong?

这感觉松散的联系<一个href=\"http://stackoverflow.com/questions/6141988/ef-4-1-loading-filtered-child-collections-not-working-for-many-to-many/6142283#6142283\">EF 4.1装载过滤子集合不工作了很多一对多,但我无法解释如何做到这一点适用于这里。

This feels loosely related to EF 4.1 loading filtered child collections not working for many-to-many but I cannot explain how this would apply here.

UPDATE1
以下的例外是由以下中的第一个例子中提供的步骤弹出

Update1: The following exception would popup by following the steps provided in the first example:

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>

在code来实现这一(不是由我亲自写的,但另一个团队成员):

The code to achieve this (not written by me personally, but another team-member):

        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();

数据是包含从客户端后数据的对象。 survey.CanAdministrate(上下文)使用上下文来读取DB OrganisationalUnits整个树决定作用。

data is an object containing the post-data from the client. survey.CanAdministrate(Context) uses the Context to read the whole tree of OrganisationalUnits from the DB to determine roles.

推荐答案

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

This is by design and IMHO it is very good feature. Context internally turns off lazy loading in some operations and validation is one of them. This is part of internal implementation of the method which causes it:

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

为什么好?因为它避免了万一漏水延迟加载,当你不希望他们。顺便说一句。如果你放在属性验证逻辑,没有加载你没有错。这是你的责任,以确保所有必要的属性都验证之前填补。

Why is it good? Because it avoids leaky lazy loads in case when you don't want them. Btw. if you placed validation logic on property which doesn't have to be loaded you did it wrong. It is your responsibility to ensure that all necessary properties are filled prior to validation.

这篇关于懒惰/递延不按时链接加载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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