为 One-to-One 构建 LINQ 查询并按 child 过滤
Build LINQ query for One-to-One and filtering by child
我有一个非常简单的模型,其中两个实体通过参考导航属性关联为 One-to-One:
class Post //"Main"
{
public int RowId { get; set; }
public string SomeInfo { get; set; }
public FTSPost FTSPost { get; set; }
}
class FTSPost //"Child"
{
public int RowId { get; set; }
public Post Post { get; set; }
public string Content { get; set; }
public string Match { get; set; }
}
我不确定它是否重要,但 FTSPost 代表 FTS5 SQLite 的虚拟 table 我正在关注 this exmaple 所以 FTSPost 用于自由文本搜索功能。我需要做的只是根据文本搜索结果从 table 中检索整行数据,而不仅仅是示例中的文本本身。 IE。我正在搜索 FTSPost 的 Content
,需要获取 Post 的相应 SomeInfo
,而不仅仅是 Content
本身。注意:Match
是用于搜索的服务属性,它绑定到FTSPosts table的名称。它有效,所以我可以像示例中那样检索 Content
。
明显的(对我来说)查询不起作用,它产生零结果:
//Doesn't work! -- zero results :(
results = _context.Posts.Where(m => m.FTSPost.Match == "text for search");
SELECT *
FROM "Posts" AS "m"
LEFT JOIN "FTSPosts" AS "f" ON "m"."RowId" = "f"."RowId"
WHERE "f"."FTSPosts" = "text for search"
但是,以下不错的原始 SQL 查询运行良好,但我无法确定如何在 LINQ 中实现它!我试图按原样重复它,使用双“from”子句,但它转换为 CROSS JOIN 并且也不起作用。请帮忙! P.S。我使用 EF Core 5。
//It works!!
SELECT *
FROM "Posts" AS "m", "FTSPosts" AS "f"
WHERE "f"."FTSPosts" = "text for search" AND "m"."RowId" = "f"."RowId"
“明显”查询不起作用的原因是一对一关系的创建方式。尽管一对一似乎是镜像的,但方式很重要。在下面的代码中交换 Message
和 FTSMessage
之后,一切都开始工作了。生成的 SQL 查询中的 LEFT JOIN 已替换为 INNER JOIN。
正确代码:
modelBuilder.Entity<Message>(
x =>
{
x.HasOne(fts => fts.FTSMessage)
.WithOne(p => p.Message)
.HasForeignKey<Message>(p => p.RowId);
});
我有一个非常简单的模型,其中两个实体通过参考导航属性关联为 One-to-One:
class Post //"Main"
{
public int RowId { get; set; }
public string SomeInfo { get; set; }
public FTSPost FTSPost { get; set; }
}
class FTSPost //"Child"
{
public int RowId { get; set; }
public Post Post { get; set; }
public string Content { get; set; }
public string Match { get; set; }
}
我不确定它是否重要,但 FTSPost 代表 FTS5 SQLite 的虚拟 table 我正在关注 this exmaple 所以 FTSPost 用于自由文本搜索功能。我需要做的只是根据文本搜索结果从 table 中检索整行数据,而不仅仅是示例中的文本本身。 IE。我正在搜索 FTSPost 的 Content
,需要获取 Post 的相应 SomeInfo
,而不仅仅是 Content
本身。注意:Match
是用于搜索的服务属性,它绑定到FTSPosts table的名称。它有效,所以我可以像示例中那样检索 Content
。
明显的(对我来说)查询不起作用,它产生零结果:
//Doesn't work! -- zero results :(
results = _context.Posts.Where(m => m.FTSPost.Match == "text for search");
SELECT *
FROM "Posts" AS "m"
LEFT JOIN "FTSPosts" AS "f" ON "m"."RowId" = "f"."RowId"
WHERE "f"."FTSPosts" = "text for search"
但是,以下不错的原始 SQL 查询运行良好,但我无法确定如何在 LINQ 中实现它!我试图按原样重复它,使用双“from”子句,但它转换为 CROSS JOIN 并且也不起作用。请帮忙! P.S。我使用 EF Core 5。
//It works!!
SELECT *
FROM "Posts" AS "m", "FTSPosts" AS "f"
WHERE "f"."FTSPosts" = "text for search" AND "m"."RowId" = "f"."RowId"
“明显”查询不起作用的原因是一对一关系的创建方式。尽管一对一似乎是镜像的,但方式很重要。在下面的代码中交换 Message
和 FTSMessage
之后,一切都开始工作了。生成的 SQL 查询中的 LEFT JOIN 已替换为 INNER JOIN。
正确代码:
modelBuilder.Entity<Message>(
x =>
{
x.HasOne(fts => fts.FTSMessage)
.WithOne(p => p.Message)
.HasForeignKey<Message>(p => p.RowId);
});