2016-07-26 1 views
2

私はEntity FrameworkでデータベースにアクセスするWeb APIプロジェクトでLINQを使用しています。スカッフォールディングを使用してAPIコントローラを作成しましたLinq式でのメソッドの使用

代わりにDTOを使用するようにWeb APIでEFモデルクラスが公開されないようにします。私は、DTOを使用するコントローラメソッドを変更し、特定のエンティティのモデルクラスとDTOの間で値をコピーする "Translate"メソッドを用意しました。クラス内のいくつかのメソッドでそれを使用します。

私は、FirstName、LastName、MiddleNameという3つのプロパティを持つ単純なPersonクラスを使用しています。

public IQueryable<PersonDto> GetPersons() 
{ 
    var personDtos = from p in db.Persons 
    order by p.LastName, p.FirstName 
    select new PersonDto() 
    { 
     FirstName = p.FirstName, 
     LastName = p.LastName, 
     MiddleName = p.MiddleName 
    }; 

    return personDtos; 
} 

private PersonDto Translate(Person p) 
{ 
    if (person == null) 
     return null; 

    return new PersonDto() 
    { 
     FirstName = p.FirstName, 
     LastName = p.LastName, 
     MiddleName = p.MiddleName 
    } 
} 

あなたは以下のように、LINQの式に翻訳メソッドを呼び出すことにより、リファクタリング機会があります見ることができるように:

public IQueryable<PersonDto> GetPersons() 
{ 
    var personDtos = from p in db.Persons 
    order by p.LastName, p.FirstName 
    select Translate(p); 

    return personDtos; 
} 

私はそれを実行したとき、私は例外を取得除いて、良いようです:エンティティへ

LINQは方法を認識しない

「を翻訳」この作品を作るための方法はありますか?データモデルのいくつかのクラスにはかなりのプロパティがありますので、可能であれば、ここでTranslateメソッドを呼び出すとよいでしょう。

+0

それが投影を使用することをお勧めします、私はmymodelというのエンティティを転送するAutoMapperを使用するpreffer、それは例db.Persons.Where(...)のために、非常に使いやすいです。ProjectTo ()。ToListメソッド()。 –

答えて

2

にそれを変更することができます。一つの方法は、AsEnumerable()を呼び出すと、あなたの方法ではなく

var personDtos = from p in db.Persons.AsEnumerable() 
order by p.LastName, p.FirstName 
select Translate(p); 
+0

これを動作させるにはpersonDtos.AsQueryable()をキャストする必要があるようです。しかし、大したことではありませんが、db.persons orderby p.LastName、p.FirstNameでvar persons = pを使用し、結果をループしてそれぞれを呼び出すのと同じくらい効率的かどうかはわかりません。私はまた、1つのPersonを取得するためにメソッドでTranslateを使用するつもりでしたが、これは簡単であることがわかりました:var person = await db.Persons.SingleOrDefaultAsync(p => p.id == id); var personDto =翻訳(人); – DesertFoxAZ

1

LinqToEntitiesは、メソッドTranslate()をデータベースで実行可能なものに変更する方法を知らない。

var personDtos = (from p in db.Persons 
    order by p.LastName, p.FirstName 
    select p) 
    .AsEnumerable() 
    .Translate(p); 

はあなたが非常に近くなります:AsEnumerable()は、呼び出された後、その処理は、クライアント側に起こるようになります。しかし、Translate()はIEnumerableではなく、1人の人物を扱います。それはどのようにないアイデアを持っていないので、あなたは変換できません原因LINQ to Entitiesは、SQLクエリとあなたの方法への発現を翻訳しているの

private IEnumerable<PersonDto> Translate(IEnumerable<Person> persons) 
{ 
    if (persons == null) yield break; 

    foreach (var p in persons) 
    { 
     yield return new PersonDto() 
     { 
      FirstName = p.FirstName, 
      LastName = p.LastName, 
      MiddleName = p.MiddleName 
     } 
    } 
} 
-1

あなたはProjectToAutoMapperの照会可能な拡張機能を使用することができLINQ to objectsに呼び出されることです。

db.Persons.ProjectTo<PersonDTO>().ToList() 
+0

これは「リンクのみ」の回答に非常に近いものです。いくつかのサンプルや追加情報が参考になります。 – DVK

関連する問題