web-dev-qa-db-ja.com

エンティティフレームワークの連合

2つのテーブルがあります。乗り物と労働者です。

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クエリで構築できません。

16
Naor

投影では、マップされたエンティティタイプを作成できません。前の例は、投影に使用される新しい特殊なタイプを作成する場合にのみ機能します。

public class VehicleResult
{
    public 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;
}  
15
Ladislav Mrnka

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が必要ですか?

5
Magnus