Кто-нибудь испытал следующее?Проверка объектов с полями, которые ссылаются на другие сущности, выдает ошибку, в которой говорится, что поле отсутствует и что при отладке программы и проверке сущностей заполненные поля .
Это происходило со мной в двух случаях, и похоже, что есть некоторая проблема с отложенной загрузкой, как будто отложенная загрузка не дает ответа достаточно быстро.
У нас есть эта (упрощенная) модельгде
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 из 10 развыдать ошибку проверки, что поле 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));
}
}
}
Это вернет ValidationErrors для значений [4,5], тогда как Questions
при проверке через отладчик действительно содержит вопросы с Id
s4 и 5. Если бы я на мгновение приостановил отладчик в if
-состоянии, проверка прошла бы правильно после этого.
Странно то, что я (сознательно) не испытывал этих ошибок раньше ичто я не обновлял библиотеки или программное обеспечение базы данных.
Эта ситуация меня немного пугает, так как кажется, что я не могу полагаться на Lazy Loading, которая всегда работает.Или, может быть, я что-то не так делаю?
Это похоже на то, что 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
- это объект, содержащий пост-данные от клиента.survey.CanAdministrate(Context)
использует контекст для считывания всего дерева OrganisationalUnits из БД для определения ролей.