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

有人经历过以下情况吗? 使用引用其他实体的字段validation对象会向您发出错误,指出该字段不存在,并且当您调试程序时,您将检查填充字段的实体。

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

我们有这个(简化)模型在哪里

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()它将在10次中的9次抛出validation错误,即OU字段是必需的并且它不存在。

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

 public class SurveyQuestionMultipleChoiceMultiSelect : SurveyQuestionMultipleChoice { public override IEnumerable validateValue(string _, IEnumerable 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,而通过调试器检查的问题确实包含Id s 4和5的问题。如果我在if -statement上暂停调试器, ifvalidation将在之后正确进行。

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

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

这与EF 4.1加载过滤的子集合松散相关,这些集合不适用于多对多但我无法解释这在这里是如何应用的。

Update1 :按照第一个示例中提供的步骤弹出以下exception:

 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.b__12() at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) InnerException:  

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

  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是包含来自客户端的post-data的对象。 survey.CanAdministrate(Context)使用Context从DB中读取OrganisationalUnits的整个树来确定角色。

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

 public virtual DbEntityValidationResult GetValidationResult(IDictionary 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; } 

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