Союз в сущности
У меня есть две таблицы: Транспортные средства и рабочие.
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.
Ответы
Ответ 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)