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

Союз в сущности

У меня есть две таблицы: Транспортные средства и рабочие.

Vehicle(Id, Number)
Workers(Id, Name, ContractorVehicleNumber)

Я хотел бы написать лямбда-запрос, чтобы вернуть все транспортные средства и транспортные средства подрядчика. Что-то вроде в sql:

SELECT Id, Number
FROM Vehicle
UNION
SELECT NULL, ContractorVehicleNumber
FROM Workers

Это то, что я сделал:

public IQueryable<Vehicle> Get(bool includeContractorVehicles)
{
    IQueryable<Vehicle> query = GetQuery();

    if (includeContractorVehicles == true)
    {
        WorkerRepository rep = new WorkerRepository();
        IQueryable<Vehicle> contractorsVehicles = rep.GetWirkers().
            Select(x => new Vehicle()
            {
                VehicleNumber = x.ContractorVehicleNumber
            });
        query = query.Union(contractorsVehicles);
    }

    return query;
}  

Но я получаю исключение:

Объект или сложный тип "XXXXXXXX" не может быть сконструирован в запросе LINQ to Entities.

4b9b3361

Ответ 1

Вы не можете построить тип сопоставленного объекта в проекции. Ваш прежний пример будет работать только при создании нового специального типа, используемого для проецирования:

public class VehicleResult
{
    pubic string Number { get; set; }
    ... // If you don't need more then one column you can use simple type instead of custom class
}

И ваш метод будет выглядеть так:

public IQueryable<VehicleResult> Get(bool includeContractorVehicles)
{
    IQueryable<VehicleResult> query = GetQuery().Select(v => new VehicleResult { ... });

    if (includeContractorVehicles == true)
    {
        WorkerRepository rep = new WorkerRepository();
        IQueryable<VehicleResult> contractorsVehicles = rep.GetWorkers().
            Select(x => new VehicleResult()
            {
                Number = x.ContractorVehicleNumber
            });
        query = query.Union(contractorsVehicles);
    }

    return query;
}  

Ответ 2

Вы не можете создавать сущности в инструкции select. Вместо этого попробуйте:

public class VehicleDTO
{
  public int Id { get; set; }
  public int Number { get; set; }
} 

public IQueryable<VehicleDTO> Get(bool includeContractorVehicles)
{
    var query = GetQuery().Select(x => new VehicleDTO(){ ID = c.ID, Number = c.Number });

    if (includeContractorVehicles)
    {
        WorkerRepository rep = new WorkerRepository();
        var contractorsVehicles = rep.GetWirkers().
            Select(x => new VehicleDTO(){ Number = x.ContractorVehicleNumber});
        query = query.Union(contractorsVehicles);
    }

    return query;
} 

Также вы уверены, что хотите Union, а не Concat?

Ответ 3

Попробуйте это...

   var unionResult = Context.Vehicles.Select(s => new {s.id, s.Number})
                  .Union(Context.Workers{w => new {null, w.ContractorVehicleNumber})

и верните этот путь

  return new ((IQueryable<Vehicle>)(unionResult)