【问题标题】:How do you use Linq to connect tables in different databases?如何使用 Linq 连接不同数据库中的表?
【发布时间】:2010-10-21 10:11:27
【问题描述】:

我是一个 Linq 新手,我找不到任何文档来帮助我解决这个看似非常微不足道的问题 - 所以我们将不胜感激您的帮助!

我在数据库DB1 中有一个表Table1,它在同一台服务器上的数据库DB2 中有一个“伪”外键Table2ID 到表Table2。 “伪”,因为显然我不能有一个跨越两个数据库的实际 FK。

现在我在玩 O/R 设计器,我喜欢将数据库对象带入设计器时生成所有关系的方式……非常酷!我希望我的Table1 对象与Table2 有关系,就像它与DB1 中的所有“真实”外键相关对象有关系一样。但我无法将Table2 带入我的数据库图中,因为它位于错误的数据库中。

为了综合这一点,我尝试在DB1 中创建一个视图Table2,它就是select * from DB2..Table2。啊哈,现在我可以将Table2 对象放入我的图表中。我什至可以在Table1Table2 之间建立父/子关系。但是当我查看生成的代码时,Table1 仍然与Table2 没有任何关系,我觉得这最令人困惑。

我是否在某处遗漏了一步?有没有更好/推荐的方法?

谢谢!


稍后...

按照一个人的建议,我尝试通过复制同一数据库中相关对象的所有结构来使用访问Table2 所需的所有方法填充Table1 的部分类。

这实际上适用于读取,但是当我尝试更新或插入记录时,我得到了一个异常:

An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported.

所以看起来 Linq 的设计者实际上已经考虑过这种情况,并决定不允许连接不同数据库中的对象。真是太可惜了……:(


...甚至更晚...

感谢@williammandra.com,我发现您需要手动在视图上创建主键。但是还有另一个问题:由于某种原因,当您从视图 Table2 加载一个值并将其设置在新记录 Table1 上,然后提交更改时,它会尝试将 new 记录插入Table2,这显然会导致 PK 违规。知道为什么会发生这种情况,以及如何解决吗?

【问题讨论】:

标签: c# linq linq-to-sql views or-designer


【解决方案1】:

视图没有主键(没有它,O/R 设计者无法创建关系)。您使用视图的解决方案让您走到了一半……您缺少的步骤是在 Table2 视图中的关键字段的 O/R 设计器中将“主键”属性设置为 true。您仍然需要手动创建关联,但是一旦您保存了 dbml,关联就会显示在生成的代码中。

【讨论】:

  • 谢谢你——在你写这篇文章的同时,我自己也在发现这个!
  • 唯一的问题是,由于某种原因,当您将“外键”设置为视图中的加载值时,它不接受;它尝试插入一条新记录,您会收到主键违规错误。您是否碰巧知道解决此问题的“秘密开关”是什么?
  • 啊哈,我在相关表中遇到了同样的问题。所以这不仅仅是关于观点。因此,这个问题的正确答案归功于您(和赏金!)在这里;我将下一个问题作为一个单独的问题发布。谢谢!
【解决方案2】:

您可以创建两个 dbml,每个 db 一个。然后加入查询中的表:

var tb1 = DataContext1.Table1
var tb2 = DataContext2.Table2

var result = (from t1 in tb1
              join t2 in tb2 on tb1.column equals tb2.column
              where ...
              select ...
             )

您也可以将 tb2 = 设置为您的视图而不是另一个数据上下文...

【讨论】:

  • 这会起作用,但这并不是我想要的效果。如果您在同一个数据库中有两个表,那么 O/R 设计器会在两者之间创建关系,例如Table1.Table2 - 我想要在我的数据上下文中使用相同的接口,只是在不同的数据库中使用 Table2。
  • 您应该可以在dbml设计器中右键单击视图并转到添加->关联以创建视图和表之间的关系。
【解决方案3】:

假设您可以从另一个数据库访问一个数据库,您可以通过手动编辑 .dbml 文件来做到这一点。

<Table Name="Table1.dbo.Table" Member="MemberObject"> 
<Table Name="Table2.dbo.Table" Member="MemberObject">

您实际上可以通过查看表的属性并更改源来做到这一点。

【讨论】:

  • 这样做的问题是,如果他需要重新生成 dbml,他的更改将会丢失
猜你喜欢
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多