System.NotSupportedException: Явное построение типа объекта в запросе недопустимо [дублировать]

Недавно я создал Boundary, библиотеку CSS + JS для решения таких проблем. Граница создает элементы, которые полностью отделены от CSS существующей веб-страницы.

Возьмите создание диалогового окна, например. После установки Boundary вы можете сделать это в своем скрипте содержимого

var dialog = Boundary.createBox("yourDialogID", "yourDialogClassName");

Boundary.loadBoxCSS("#yourDialogID", "style-for-elems-in-dialog.css");

Boundary.appendToBox(
    "#yourDialogID",
    ""
);

Boundary.find("#submit_button").click(function() {
  // some js after button is clicked.
});

Элементы в #yourDialogID не будут затронуты существующей веб-страницей. И функция find () возвращает регулярный элемент DOM jQuery, чтобы вы могли делать с ним все, что хотите.

Надеюсь, это поможет. Пожалуйста, дайте мне знать, если у вас есть какие-либо вопросы.

https://github.com/liviavinci/Boundary

35
задан rejnev 13 July 2016 в 01:05
поделиться

8 ответов

Сущности могут создаваться вне запросов и вставляться в хранилище данных с использованием DataContext. Затем вы можете получить их с помощью запросов. Однако вы не можете создавать объекты как часть запроса.

21
ответ дан Martin Peck 18 August 2018 в 10:53
поделиться
  • 1
    thats означает больше строк кода? – Angel Escobedo 24 April 2009 в 20:58
  • 2
    Как передать значения выбора из возвращаемого запроса в Entity, я имею в виду не использовать члены, как «varReturningQuery as ProductionEntity»? – Angel Escobedo 24 April 2009 в 21:00

Я построю анонимный тип, использую IEnumerable (который сохраняет отложенное выполнение), а затем повторно воссоздает объект datacontext. Оба Employee и Manager являются объектами datacontext:

    var q = dc.Employees.Where(p => p.IsManager == 1)
            .Select(p => new { Id = p.Id, Name = p.Name })
            .AsEnumerable()    
            .Select(item => new Manager() { Id = item.Id, Name = item.Name });
5
ответ дан Ash Machine 18 August 2018 в 10:53
поделиться

Я нашел еще одно решение этой проблемы, которое позволяет сохранить результат как IQueryale, поэтому он фактически не выполняет запрос до тех пор, пока вы его не выполнили (например, с методом ToList ()).

Итак, linq не позволяет создавать объект как часть запроса? Вы можете перенести эту задачу в базу данных и создать функцию, которая будет захватывать нужные вам данные. После импорта функции в контекст данных вам просто нужно установить тип результата на тот, который вы хотите.


Я узнал об этом, когда мне пришлось написать фрагмент кода, который создайте IQueryable<T>, в котором элементы фактически не существуют в таблице, содержащей T.

0
ответ дан jahu 18 August 2018 в 10:53
поделиться

Я просто столкнулся с той же проблемой.

Я нашел очень легкое решение.

var a = att as Attachment;

Func<Culture, AttachmentCulture> make = 
    c => new AttachmentCulture { Culture = c };

var culs = from c in dc.Cultures
           let ac = c.AttachmentCultures.SingleOrDefault( 
                                           x => x.Attachment == a)
           select ac == null ? make(c) : ac;

return culs;
9
ответ дан leppie 18 August 2018 в 10:53
поделиться
  • 1
    выбор может быть лучше написан как select ac ?? сделать (с); – recursive 28 October 2009 в 17:45
  • 2
    Отличное решение - спасибо! Любые идеи, почему это не допускается без этого? – Whisk 1 July 2010 в 14:20
  • 3
    @Whisk - в случае, если вас все еще интересует, я нашел social.msdn.microsoft.com/forums/en-US/linqprojectgeneral/… - '... Конструирование экземпляров сущностей вручную в качестве проекции загрязняет кеш с потенциально искаженными объектами ... ' – Alex Humphrey 10 September 2010 в 09:04

Я обнаружил, что если вы выполняете .ToList () в запросе, прежде чем пытаться конструировать новые объекты, он работает

9
ответ дан mimo 18 August 2018 в 10:53
поделиться

Вот еще одно обходное решение:

  1. Создайте класс, который происходит из вашего класса LINQ to SQL. Я предполагаю, что класс L2S, который вы хотите вернуть, это Order:
    internal class OrderView : Order { }
    
  2. Теперь напишите запрос следующим образом:
    var query = from o in db.Order
                select new OrderView // instead of Order
                {
                   OrderID = o.OrderID,
                   OrderDate = o.OrderDate,
                   // etc.
                };
    
  3. Верните результат в Order, например:
    return query.Cast<Order>().ToList(); // or .FirstOrDefault()
    
  4. (или использовать что-то более разумное, например BLToolkit / LINQ to DB)

Примечание: я не тестировал, или нет; он работает для извлечения данных, которые мне нужны.

8
ответ дан pbz 18 August 2018 в 10:53
поделиться
  • 1
    Brilliant! Хотя мне не нужно было отбрасывать назад – irfandar 28 June 2014 в 13:29
  • 2
    Я согласен, что это отличное решение! Если есть техническая причина, по которой я не должен проектироваться на класс сущности, тогда это нормально, я не буду, но кто хочет переопределить новый (потенциально длинный) класс с одинаковой формой? Никто, вот кто. Это решение разрешает его без явного переопределения. Отличная работа pbz, прибила ее. – dean grande 20 August 2015 в 12:35

В книге «70-515 Разработка веб-приложений с Microsoft .NET Framework 4 - Учебный комплект для самостоятельного обучения» на стр. 638 приведен следующий пример для вывода результатов строго типизированному объекту:

    IEnumerable<User> users = from emp in employees where emp.ID !=0
    select new User
    {
    Name = emp.First + " " + emp.Last,
    EmployeeId = emp.ID
    }

Совет Марк Пекс, похоже, противоречит этой книге - однако для меня этот пример все еще отображает вышеупомянутую ошибку, оставляя меня несколько смущенным. Связано ли это с различиями в версии? Любые предложения приветствуются.

0
ответ дан Stone 18 August 2018 в 10:53
поделиться
  • 1
    Вышеприведенный пример работает, если «Пользователь» не является частью DataContext. – Stone 25 June 2012 в 10:56

Я считаю, что это ограничение очень раздражает и противоречит общей тенденции не использовать SELECT * в запросах.

Тем не менее с анонимными типами c # существует обходное решение, путем извлечения объектов в анонимного типа, а затем скопируйте его в правильный тип.

Например:

var q = from emp in employees where emp.ID !=0
select new {Name = emp.First + " " + emp.Last, EmployeeId = emp.ID }
var r = q.ToList();
List<User> users = new List<User>(r.Select(new User
   {
        Name = r.Name,
        EmployeeId = r.EmployeeId 
   }));

И в случае, когда мы имеем дело с одним значением (как в ситуации, описанной в вопросе), это еще проще, и нам просто нужно чтобы скопировать непосредственно значения:

var q = from emp in employees where emp.ID !=0 
select new { Name = emp.First + " " + emp.Last, EmployeeId = emp.ID }
var r = q.FirstOrDefault();
User user = new User { Name = r.Name, EmployeeId = r.ID };

Если имя свойства соответствует столбцам базы данных, мы можем сделать это еще проще в запросе, выполнив select

var q = from emp in employees where emp.ID !=0 
select new { emp.First, emp.Last, emp.ID }

One может пойти вперед и написать выражение лямбда, которое может автоматически копироваться на основе имени свойства, без необходимости явно указывать значения.

14
ответ дан yoel halb 18 August 2018 в 10:53
поделиться
  • 1
    Я согласен, что ограничение очень раздражает. Однако вызов ToList в вашем решении поместит результаты в память, что, вероятно, нежелательно для больших наборов данных. – Protector one 7 August 2017 в 15:06
Другие вопросы по тегам:

Похожие вопросы: