1

我正在使用 Simple.Data 并且一直在尝试找到一个示例,该示例可以让我使用 WHERE 子句中的唯一条件来自连接表进行连接。我见过的所有示例总是在 WHERE 中包含主表中的至少一列。以以下数据为例:

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);
}

我试图找出我需要在 Simple.Data 中使用的语法来获得类似于此 T-SQL 的内容:

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

当我传入“CodeMash2013”​​事件代码时,最终结果应该只有 EventId 1 的三个 Door 行。谢谢!

4

2 回答 2

3

首先,一般的一点:因为你已经有了针对连接事件表的标准,所以 LEFT OUTER 是多余的;仅返回具有匹配事件代码的行,这意味着仅从门连接到事件成功的那些行。

如果您在数据库中设置了参照完整性,并且具有从 Doors 到 Events 的外键关系,那么 Simple.Data 可以自动处理连接。考虑到这一点,此代码将适用于 InMemoryAdapter 和 SQL Server:

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

更新:此答案适用于使用 Simple.Data SQL Server Provider,而不是 InMemoryAdapter

您可能会为此使用以下内容:

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 提供程序,这两个函数都生成 LEFT JOIN 语句,因为 LEFT JOIN 和 LEFT OUTER JOIN 在 t-sql 中是同义词。

如果出于某种原因需要使用别名,则语法略有不同。

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 回答