Почему я получаю ошибку синтаксического анализа XML: корневой элемент не найден (даже если я сравниваю примитивные типы, как того требует внутреннее исключение)? - PullRequest
0 голосов
/ 08 января 2019

При попытке выполнить следующее я получаю ошибку синтаксического анализа XML: в Firefox не найден корневой элемент. В Internet Explorer я не получаю ошибку, но она не работает так, как я ожидаю.

   IList<Gu> gus = Context.GuSet.Where(gu => gu.Id == id).OrderBy(gu=>gu.User.Name).ToList();

            IQueryable<UserModel> users = TabWebContext.UserSet.Select(o => new UserModel
            {
                Id = o.Id,
                UserName = o.Name,
                SomeBoolean= gus.Where(gu => gu.User.Id == o.Id).FirstOrDefault().SomeBoolean
            }

Внутреннее исключение моего ServerLog:

System.NotSupportedException: невозможно создать постоянное значение введите "XY.Z.Gu". Только примитивные типы или типы перечисления поддерживаются в этом контексте. в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.ConstantTranslator.TypedTranslate (ExpressionConverter родитель, ConstantExpression linq) в System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TypedTranslator`1.T ...

.... ... MyController.cs: line 531

Я понимаю, что Entity Framework не знает, как перевести сравнение двух сущностей в SQL. Но идентификаторы, которые я сравниваю, - это примитивные типы (целые числа), которые должны работать.

1 Ответ

0 голосов
/ 08 января 2019

Во-первых, проблема XML заключается только в том, что код вашего контроллера дает сбой, и какая бы (отсутствие?) Обработка исключений означала, что он просто не отправляет разумный HTML обратно в браузер. Пока игнорируйте это - если вы решите проблему с EF, она, вероятно, исчезнет.

Я предполагаю, что EF не нравится проекционная часть, пытаясь понять, как преобразовать существующий IList <> во что-то, что он может использовать в SQL. вы можете обойти это, выполнив это, хотя это не приведет к IQueryable <> в конце курса (что может или не может быть проблемой в зависимости от вашего объема данных и конкретного варианта использования)

IList<Gu> gus = Context.GuSet
  .Include(gu=>gu.User)//make sure the User property is hydrated - this might have been your actual problem?  not 100% sure though
  .Where(gu => gu.Id == id)
  .OrderBy(gu=>gu.User.Name).ToList();

//first get a list of users.
var users = TabWebContext.UserSet.Select(o => new UserModel
{
    Id = o.Id,
    UserName = o.Name
})
//fetch into List<UserModel> - note the DB will now get hit HERE
//with something like "select id, name from users"
.ToList();

//as users is now a List<UserModel> we can iterate over it and change each entry.
users.ForEach(u=>
  //Set SomeBoolean for each UserModel entry based on 'gus' list.
  //also note now dealing with case where FirstOrDefault returns a null
  //object and using default of false if it does.
  u.SomeBoolean=gus.FirstOrDefault(gu => gu.User.Id == u.Id)?.SomeBoolean ?? false);

Это должно работать , но будет оценивать фактический запрос SQL на более раннем этапе, чем ваш код (так как вы только что получили IQueryable<>, он бы попадал в БД только при первой попытке сделать что-то с users)

...