0

私の問題は複雑なデータベースに関するものなので、以下の簡略化されたバージョンを使用しました。

私は3つのテーブルを持っています。それらを呼びましょう:

Course
    - id
    - name

Student
    - id
    - name

StudentCourses
    - id
    - student_id
    - course_id

StudentCoursesは、他の両方のテーブルに関連するように設定されています。これは、かなり通常の多対多のパターンです。

パーシャルを使用してStudentオブジェクトを拡張し、Studentクラスにかなり基本的なメソッドを追加して、すべてのクラスを取得しました。

// Partial to add helper method to LINQ generated Student class
public partial class Student {

    // Get courses that this student is enrolled.
    public IQueryable<Course> GetCourses(){
        return this.StudentCourses.Select(d=>d.Course);
    }
}

これは内部で結合を使用する可能性があると予想しましたが、SQLクエリをログに記録すると、実際には結合ごとに1つの「SELECT*FROMコース」が作成されることがわかります。

この動作を実行するためのより良い方法は何でしょうか?行ごとに1つの選択は、ひどく非効率的なようです。

さらなる調査 いくつかのコメントの後、私はさらに調査することにしました。私は次のことを発見しました:

MyDataContext db = new MyDataContext();
var student = db.Students.Single(i=>i.id);

var testOne = db.StudentCourses.Where(u=>u.student_id == student.id).
                                      Select(d=>d.Courses).ToList();

var testTwo = student.StudentCourses.Select(d=>d.Courses).ToList();

テスト1では、実行されるSQLはJOINを使用するため、単一のデータベース呼び出しです。テスト2では、SQLは1つの選択されたPERコースです。これは問題です。

これは予想される動作ですか?私が推測する最初のタイプにリファクタリングすることはできますが、2番目のテストのロジックを好みます。

4

1 に答える 1

1

LinqToSqlの場合は、 DataLoadOptionsを使用します

例 :

public IQueryable<Course> GetCourses(){
    var dlo = new DataLoadOptions();
    dlo.LoadWith<StudentCourses>(d => d.Course);
    this.LoadOptions = dlo;

    return this.GetTable<StudentCourses>().Select(d=>d.Course);
}

これがお役に立てば幸いです!!

于 2012-10-11T12:28:16.083 に答える