延迟/延迟加载链接不及时?
有人经历过以下情况吗? 使用引用其他实体的字段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上暂停调试器, if
validation将在之后正确进行。
奇怪的是,我之前没有(明知)遇到过这些错误,而且我没有更新任何库或数据库软件。
这种情况让我感到害怕,因为我似乎不能依赖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
它为什么好? 因为它可以避免泄漏的延迟负载,如果你不想要它们。 顺便说一句。 如果你将validation逻辑放在不必加载的属性上,你就错了。 您有责任确保在validation之前填写所有必要的属性。