我正在使用 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"时,最终结果应该只是事件 ID 1 的三个门行。 谢谢!
首先,一般观点:由于您有针对联接事件表的条件,因此 LEFT OUTER 是多余的; 只会返回具有匹配事件代码的行,这意味着只有那些从门到事件的联接成功
。如果您在数据库中设置了引用完整性,并且具有从门到事件的外键关系,则 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);
更新:此答案适用于使用 Simple.Data SQL Server 提供程序,而不是 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 文档站点上找到更多联接示例。到达该处时单击显式联接。