1

Simple.Dataを使用していて、WHERE句の唯一の条件が結合テーブルからのものである結合を実行できる例を見つけようとしています。私が見たすべての例では、WHEREに含まれるプライマリテーブルに常に少なくとも1つの列があります。たとえば、次のデータを取り上げます。

private void TestSetup()
{
    var adapter = new InMemoryAdapter();
    adapter.SetKeyColumn("Events", "Id");
    adapter.SetAutoIncrementColumn("Events", "Id");
    adapter.SetKeyColumn("Doors", "Id");
    adapter.SetAutoIncrementColumn("Doors", "Id");
    adapter.Join.Master("Events", "Id").Detail("Doors", "EventId");
    Database.UseMockAdapter(adapter);
    db.Events.Insert(Id: 1, Code: "CodeMash2013", Name: "CodeMash 2013");
    db.Events.Insert(Id: 2, Code: "SomewhereElse", Name: "Some Other Conf");
    db.Doors.Insert(Id: 1, Code: "F7E08AC9-5E75-417D-A7AA-60E88B5B99AD", EventID: 1);
    db.Doors.Insert(Id: 2, Code: "0631C802-2748-4C63-A6D9-CE8C803002EB", EventID: 1);
    db.Doors.Insert(Id: 3, Code: "281ED88F-677D-49B9-84FA-4FAE022BBC73", EventID: 1);
    db.Doors.Insert(Id: 4, Code: "9DF7E964-1ECE-42E3-8211-1F2BF7054A0D", EventID: 2);
    db.Doors.Insert(Id: 5, Code: "9418123D-312A-4E8C-8807-59F0A63F43B9", EventID: 2);
}

このT-SQLに似たものを取得するために、Simple.Dataで使用する必要のある構文を理解しようとしています。

SELECT d.Code FROM Doors AS d INNER JOIN Events AS e ON d.EventID = e.Id WHERE e.Code = @EventCode

「CodeMash2013」のイベントコードを渡すと、最終的な結果はEventId1の3つのDoor行のみになります。ありがとう!

4

2 に答える 2

3

まず、一般的なポイントです。結合されたイベントテーブルに対する基準があるため、LEFTOUTERは冗長です。イベントコードが一致する行のみが返されます。これは、ドアからイベントへの結合が成功した行のみを意味します。

DoorsからEventsへの外部キー関係を使用して、データベースに参照整合性を設定している場合、Simple.Dataは結合を自動的に処理できます。このことを念頭に置いて、このコードはInMemoryAdapterとSQLServerの両方で機能します。

List<dynamic> actual = db.Doors.FindAll(db.Doors.Events.Code == "CodeMash2013")
               .Select(db.Doors.Id, db.Events.Name)
               .ToList();

Assert.AreEqual(3, actual.Count);

参照整合性を設定していない場合は設定する必要がありますが、何らかの理由で設定できない場合は、次のようにSQL Serverで機能しますが、修正したばかりのInMemoryAdapterにバグが発生します。まだリリースを行っていません:

dynamic eventAlias;
List<dynamic> actual = db.Doors.All()
              .Join(db.Events, out eventAlias)
              .On(db.Doors.EventID == eventAlias.Id)
              .Select(db.Doors.Id, db.Events.Name)
              .Where(eventAlias.Code == eventCode)
              .ToList();

Assert.AreEqual(3, actual.Count);
于 2012-12-04T15:26:04.550 に答える
0

更新:この回答は、InMemoryAdapterではなくSimple.DataSQLServerプロバイダーを使用する場合に適用されます

あなたはおそらくこれのために以下を使うことができます:

db.Doors.All()
  .Select(
    db.Doors.Code)
  .LeftJoin(db.Events).On(db.Doors.EventID == db.Events.Id)
  .Where(db.Events.Code == eventCode);

プロバイダーによっては、LeftJoinとOuterJoinの使用を試す必要がある場合があります。たとえば、ADOプロバイダーを使用している場合、LEFTJOINとLEFTOUTER JOINはt-sqlで同義語であるため、2つの関数は両方ともLEFTJOINステートメントを生成します。

何らかの理由でエイリアスを使用する必要がある場合は、構文が少し異なります。

dynamic EventAlias;
db.Doors.All()
  .LeftJoin(db.Events.As"e", out EventAlias).On(db.Doors.EventID == db.EventAlias.Id)
  .Select(
    db.Doors.Code)
  .Where(db.EventAlias.Code == eventCode);

where句に主キーテーブルのフィールドが含まれている必要がある理由はありません。結合のその他の例は、Simple.Dataドキュメントサイトにあります。そこに着いたら、[明示的結合]をクリックします。

于 2012-11-30T22:29:45.840 に答える