Подтвердить что ты не робот

Явное построение типа объекта '###' в запросе недопустимо.

Используя команды Linq и Linq To SQL datacontext, я пытаюсь экземпляр Entity, называемый "Produccion" из моего datacontext таким образом:

Demo.View.Data.PRODUCCION pocoProduccion = 
(
    from m in db.MEDICOXPROMOTORs
    join a in db.ATENCIONs on m.cmp equals a.cmp
    join e in db.EXAMENXATENCIONs on a.numeroatencion equals e.numeroatencion
    join c in db.CITAs on e.numerocita equals c.numerocita
    where e.codigo == codigoExamenxAtencion
    select new Demo.View.Data.PRODUCCION
    {
         cmp = a.cmp,
         bonificacion = comi,
         valorventa = precioEstudio,
         codigoestudio = lblCodigoEstudio.Content.ToString(),
         codigopaciente = Convert.ToInt32(lblCodigoPaciente.Content.ToString()),
         codigoproduccion = Convert.ToInt32(lblNroInforme.Content.ToString()),
         codigopromotor = m.codigopromotor,
         fecha = Convert.ToDateTime(DateTime.Today.ToShortDateString()),
         numeroinforme = Convert.ToInt32(lblNroInforme.Content.ToString()),
         revisado = false,
         codigozona = (c.codigozona.Value == null ? Convert.ToInt32(c.codigozona) : 0),
         codigoclinica = Convert.ToInt32(c.codigoclinica),
         codigoclase = e.codigoclase,
    }
).FirstOrDefault();

Во время выполнения вышеуказанного кода я получаю следующую ошибку, в которую включена трассировка стека:

System.NotSupportedException was caught
  Message="The explicit construction of the entity type 'Demo.View.Data.PRODUCCION' in a query is not allowed."
  Source="System.Data.Linq"
  StackTrace:
       en System.Data.Linq.SqlClient.QueryConverter.VisitMemberInit(MemberInitExpression init)
       en System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node)
       en System.Data.Linq.SqlClient.QueryConverter.Visit(Expression node)
       en System.Data.Linq.SqlClient.QueryConverter.VisitSelect(Expression sequence, LambdaExpression selector)
       en System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc)
       en System.Data.Linq.SqlClient.QueryConverter.VisitMethodCall(MethodCallExpression mc)
       en System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node)
       en System.Data.Linq.SqlClient.QueryConverter.Visit(Expression node)
       en System.Data.Linq.SqlClient.QueryConverter.VisitFirst(Expression sequence, LambdaExpression lambda, Boolean isFirst)
       en System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc)
       en System.Data.Linq.SqlClient.QueryConverter.VisitMethodCall(MethodCallExpression mc)
       en System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node)
       en System.Data.Linq.SqlClient.QueryConverter.ConvertOuter(Expression node)
       en System.Data.Linq.SqlClient.SqlProvider.BuildQuery(Expression query, SqlNodeAnnotations annotations)
       en System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query)
       en System.Data.Linq.DataQuery`1.System.Linq.IQueryProvider.Execute[S](Expression expression)
       en System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)
       en Demo.View.InformeMedico.realizarProduccionInforme(Int32 codigoExamenxAtencion, Double precioEstudio, Int32 comi) en D:\cs_InformeMedico\app\InformeMedico.xaml.cs:línea 602
       en Demo.View.InformeMedico.UpdateEstadoEstudio(Int32 codigo, Char state) en D:\cs_InformeMedico\app\InformeMedico.xaml.cs:línea 591
       en Demo.View.InformeMedico.btnGuardar_Click(Object sender, RoutedEventArgs e) en D:\cs_InformeMedico\app\InformeMedico.xaml.cs:línea 683
  InnerException: 

Возможно ли это в LINQ2SQL?

4b9b3361

Ответ 1

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

Ответ 2

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

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

Например:

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 }

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

Ответ 3

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

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

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;

Ответ 4

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

Ответ 5

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

  • Создайте класс, полученный из вашего класса LINQ to SQL. Я предполагаю, что класс L2S, который вы хотите вернуть, это Order:

    internal class OrderView : Order { }
    
  • Теперь напишите запрос таким образом:

    var query = from o in db.Order
                select new OrderView // instead of Order
                {
                   OrderID = o.OrderID,
                   OrderDate = o.OrderDate,
                   // etc.
                };
    
  • Верните результат в порядок, например:

    return query.Cast<Order>().ToList(); // or .FirstOrDefault()
    
  • (или используйте что-то более разумное, например BLToolkit/LINQ to DB)

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

Ответ 6

Я создаю анонимный тип, использую 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 });

Ответ 7

В книге "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
    }

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

Ответ 8

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

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


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