在运行时映射一对一关系

2024-04-02

我正在尝试升级旧的 CMS 以使用 NHibernate,并且无法对原始数据库结构产生太大影响。这是导致问题的部分。假设我有以下 2 个表:

Articles: 
- Id (PK, Identity)
- Title 
- Content 

Meta: 
- ArticleId (PK, FK to Articles)
- Description 
- Keywords 

我创建了以下课程:

public class Article { 
  public virtual int Id { get; set; } 
  public virtual string Title { get; set; } 
  public virtual string Content { get; set; } 
} 

public class Meta : IComponent { 
  public virtual string Description { get; set; } 
  public virtual string Keywords { get; set; } 
}

public interface IComponent {
}

通常,Meta 通常会映射为 Article 类上的组件(或一对一关系)属性。但是,在我正在构建的应用程序中,管理员可以启用/禁用适用于文章的组件。另外,我希望他们扩展应用程序以添加自己的组件,而无需触及 Article 类。

由于这些原因,我无法针对 Article 类添加属性。现在理想情况下,在我的代码中我希望能够说:

var articles = session.Query<Article>()
    .Fetch(a = a.Component<Meta>())
    .Where(a => a.Component<Meta>().Keywords.Contains("Some Word"))
    .ToList();

// This wouldn't generate an extra SQL statement
var keywords = articles[0].Component<Meta>().Keywords;

这将生成以下 SQL(或类似的):

SELECT * FROM Articles INNER JOIN Meta ON Articles.Id = Meta.ArticleId WHERE Meta.Keywords LIKE '%Some Word%'

是否可以映射 Component 方法,以便它执行内部联接来获取 Meta.这个概念看起来很简单,但我不知道从哪里开始。我真的很感激你的帮助。

Thanks


鉴于这种:

public class Article
{
    public virtual int ArticleId { get; set; }
    public virtual string Title { get; set; }
    public virtual string Content { get; set; }
}


public class Meta : IComponent
{
    public virtual Article Article { get; set; }

    public virtual int MetaId { get; set; }
    public virtual string Description { get; set; }
    public virtual string Keywords { get; set; }
}

AFAIK,你无法获取不属于实体的东西。因此,从您的示例来看,不可能从 Article 实体中获取 Meta。

因此,如果你想获取一篇文章的其他信息,你只需将文章加入其中,然后将完整的数据投影到你的 Linq 中,例如:

var articles =
        from a in s.Query<Article>()
        join m in s.Query<Meta>() on a equals m.Article
        where m.Keywords.Contains("Some Word")
        select new { a, m };

foreach(var x in articles)
    Console.WriteLine("{0} {1}", x.a.Title, x.m.Description);

结果查询:

select *
from [Article] article0_, [Meta] meta1_ 
where meta1_.ArticleId = article0_.ArticleId 
    and meta1_.Keywords like '%Some Word%'

另一种方法,从Meta开始,然后获取Article;在查询时,这将立即加入文章,即没有延迟加载:

var artB =
        from m in s.Query<Meta>().Fetch(x => x.Article)
        where m.Keywords.Contains("Some Word")
        select m;

foreach (var x in artB)
    Console.WriteLine("{0} {1}", x.Article.Title, x.Description);

结果查询:

select *
from [Meta] meta0_ 
left outer join [Article] article1_ on meta0_.ArticleId = article1_.ArticleId 
where meta0_.Keywords like '%Some Word%'

要保持一篇文章只有一个元,请在元的引用上添加一个唯一值:

create table Article
(
ArticleId int identity(1,1) not null primary key,
Title varchar(100) not null,
Content varchar(100) not null
);

create table Meta
(
    -- this prevents an Article having two Meta
ArticleId int not null references Article(ArticleId) unique, 

MetaId int identity(1,1) not null primary key,

Description varchar(100) not null,
Keywords varchar(100) not null
);

insert into Article(Title,Content) values('Great','Yeah')

insert into Meta(ArticleId, Description, Keywords) values(1,'Oh','Some Word');
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在运行时映射一对一关系 的相关文章

  • 为什么通过派生类对基类的引用与 :: - 运算符不明确?

    所以我想知道为什么以下钻石问题的代码片段无法编译 我知道这个问题通常是通过虚拟继承来解决的 我不是故意使用它的 该代码只是为了展示我的问题 即为什么编译器称此不明确 因此 我在 struct Base 中声明了两个成员变量 因为这两个子类
  • JSON.Net 反序列化返回“null”

    我正在使用 JSON Net 反序列化 JSON 字符串 JSON 字符串是 string testJson Fruits Apple color red size round Orange Pro
  • 如何使用 ASP.NET MVC 编辑多选列表?

    我想编辑一个如下所示的对象 我希望用 UsersGrossList 中的一个或多个用户填充 UsersSelectedList 使用 mvc 中的标准编辑视图 我只得到映射的字符串和布尔值 下面未显示 我在 google 上找到的许多示例都
  • 元组在 VS2012 中如何工作?

    Visual Studio 2012 功能 tuples但不是可变参数模板 这是如何完成的 如何在不使用可变模板的情况下实现元组 简而言之 微软做了与之前在 NET 中实现类似元组的数据类型完全相同的事情 创建许多版本 每个版本都有固定数量
  • IEnumerable 的 String.Join(string, string[]) 的类似物

    class String包含非常有用的方法 String Join string string 它从数组创建一个字符串 用给定的符号分隔数组的每个元素 但一般来说 它不会在最后一个元素之后添加分隔符 我将它用于 ASP NET 编码 以用
  • 我如何知道 C 程序的可执行文件是在前台还是后台运行?

    在我的 C 程序中 我想知道我的可执行文件是否像这样在前台运行 a out 或者像这样 a out 如果你是前台工作 getpgrp tcgetpgrp STDOUT FILENO or STDIN FILENO or STDERR FIL
  • C free() 是如何工作的? [复制]

    这个问题在这里已经有答案了 可能的重复 malloc 和 free 如何工作 https stackoverflow com questions 1119134 how malloc and free work include
  • 进程退出后 POSIX 名称信号量不会释放

    我正在尝试使用 POSIX 命名信号量进行跨进程同步 我注意到进程死亡或退出后 信号量仍然被系统打开 在进程 打开它 死亡或退出后是否有办法使其关闭 释放 早期的讨论在这里 当将信号量递减至零的进程崩溃时 如何恢复信号量 https sta
  • 带有运算符语法的错误消息,但不带有函数语法的错误消息

    为什么我在调用 unary 时收到错误消息 使用运算符语法 如果我用函数语法调用它就可以了 现场演示 https godbolt org z j7AbeQ template
  • 为什么需要数字后缀?

    C 语言 我确信还有其他语言 需要在数字文字末尾添加后缀 这些后缀指示文字的类型 例如 5m是一个小数 5f是一个浮点数 我的问题是 这些后缀真的有必要吗 或者是否可以从上下文中推断出文字的类型 例如 代码decimal d 5 0应该推断
  • 你好,我最近正在开发我的新游戏,我遇到了*无限跳跃*的问题

    所以基本上当我按跳跃 空格键时我会跳跃但是如果我连续按空格键它 只是跳啊跳啊跳等等 我不想要我只想它跳一次 code if Input GetKeyDown space isGrounded velocity y Mathf Sqrt ju
  • 使用 C# 中的 Google 地图 API 和 SSIS 包获取行驶距离

    更新 找到了谷歌距离矩阵并尝试相应地修改我的代码 我在这里收到无效参数错误 return new GeoLocation dstnc uri ToString catch return new GeoLocation 0 0 https 基
  • 用于连接 DataTable 上的动态列的动态 LINQ

    我目前遇到的情况不确定如何继续 我有两个从数据库填充的数据表 我还有一个可用的列名称列表 可用于将这两个数据表连接在一起 我希望编写一组 LINQ 查询 这些查询将 显示两个数据表中的行 内部联接 用于从一个数据表更新另一个数据表 显示一个
  • 时间:2019-03-17 标签:c++fstream并发访问

    如果从不同的进程 线程同时访问文件会发生什么 据我所知 没有锁定文件的标准方法 只有操作系统特定的功能 就我而言 文件将被经常读取而很少写入 现在如果A打开一个文件进行读取 ifstream 并开始读取块 和B打开相同的文件进行写入 ofs
  • doxygen c++:记录由“using”声明公开的私有继承成员

    作为一个例子 我有以下课程 class A public void methodOne class B private A public Brief description using A methodOne 我还没有找到强制 doxyge
  • 无法在 C# 中为 EventArgs 分配使用派生类型的事件处理程序

    所以我有一个事件声明如下 public event EventHandler OnChangeDetected 然后我有以下处理程序被分配给该事件 myObject OnChangeDetected OnTableChanged 我的理解是
  • 从 NumPy 数组到 Mat 的 C++ 转换 (OpenCV)

    我正在围绕 ArUco 增强现实库 基于 OpenCV 编写一个薄包装器 我试图构建的界面非常简单 Python 将图像传递给 C 代码 C 代码检测标记并将其位置和其他信息作为字典元组返回给 Python 但是 我不知道如何在 Pytho
  • “必须声明标量变量”错误[重复]

    这个问题在这里已经有答案了 必须声明标量变量 Id SqlConnection con new SqlConnection connectionstring con Open SqlCommand cmd new SqlCommand cm
  • 如何提高环复杂度?

    对于具有大量决策语句 包括 if while for 语句 的方法 循环复杂度会很高 那么我们该如何改进呢 我正在处理一个大项目 我应该减少 CC gt 10 的方法的 CC 并且有很多方法都存在这个问题 下面我将列出一些例如我遇到的问题的
  • 为什么表达式 a = a + b - ( b = a ) 在 C++ 中给出序列点警告?

    以下是测试代码 int main int a 3 int b 4 a a b b a cout lt lt a lt lt a lt lt lt lt b lt lt b lt lt n return 0 编译此命令会出现以下警告 gt g

随机推荐