gpt4 book ai didi

c# - 在 LINQ-to-SQL 中使用跨上下文连接

转载 作者:可可西里 更新时间:2023-11-01 09:07:43 24 4
gpt4 key购买 nike

最初我使用 LINQ-to-SQL 编写了这个查询

var result = from w in PatternDataContext.Windows
join cf in PatternDataContext.ControlFocus on w.WindowId equals cf.WindowId
join p in PatternDataContext.Patterns on cf.CFId equals p.CFId
join r in ResultDataContext.Results on p.PatternId equals r.PatternId
join fi in ResultDataContext.IclFileInfos on r.IclFileId equals fi.IclFileId
join sp in sessionProfileDataContext.ServerProfiles on fi.ServerProfileId equals sp.ProfileId
join u in infrastructure.Users on sp.UserId equals u.Id
where w.Process.Equals(processName)
select u.DistributedAppId;

当我执行它并在 QuickWatch.. 中看到 result 时,它显示了这条消息:

the query contains references to items defined on a different data context

在谷歌搜索中,我找到了 this topic在 Stackoverflow 本身,我在那里学习了模拟跨上下文连接,并且按照那里的建议,我将我的查询稍微更改为:

var result = from w in PatternDataContext.Windows
join cf in PatternDataContext.ControlFocus on w.WindowId equals cf.WindowId
join p in PatternDataContext.Patterns on cf.CFId equals p.CFId
join r in SimulateJoinResults() on p.PatternId equals r.PatternId
join fi in SimulateJoinIclFileInfos() on r.IclFileId equals fi.IclFileId
join sp in SimulateJoinServerProfiles() on fi.ServerProfileId equals sp.ProfileId
join u in SimulateJoinUsers() on sp.UserId equals u.Id
where w.Process.Equals(processName)
select u.DistributedAppId;

此查询使用这些SimulateXyz 方法:

private static IQueryable<Result> SimulateJoinResults()
{
return from r in SessionDataProvider.Instance.ResultDataContext.Results select r;
}
private static IQueryable<IclFileInfo> SimulateJoinIclFileInfos()
{
return from f in SessionDataProvider.Instance.ResultDataContext.IclFileInfos select f;
}
private static IQueryable<ServerProfile> SimulateJoinServerProfiles()
{
return from sp in sessionProfileDataContext.ServerProfiles select sp;
}
private static IQueryable<User> SimulateJoinUsers()
{
return from u in infrastructureDataContext.Users select u;
}

但即使是这种方法也没有解决问题。我仍在 QuickWatch... 中收到此消息:

the query contains references to items defined on a different data context

这个问题有什么解决办法吗?除了解决方案,我还想知道为什么问题仍然存在,以及新解决方案究竟如何解决它,以便下次我可以自己解决此类问题。顺便说一句,我是 LINQ 的新手。

最佳答案

我以前不得不这样做,有两种方法可以做到。

第一个是将所有服务器移动到一个上下文中。为此,您可以将 LINQ-to-SQL 指向单个服务器,然后在该服务器中创建 linked servers到所有其他服务器。然后,您只需从其他服务器为您感兴趣的任何表创建 View ,并将这些 View 添加到您的上下文中。

第二种是自己手动进行连接,方法是从一个上下文中提取数据,然后仅使用您需要连接到另一个上下文中的属性。例如,

int[] patternIds = SessionDataProvider.Instance.ResultDataContext.Results.Select(o => o.patternId).ToArray();
var results = from p in PatternDataContext.Patterns
where patternIds.Contains(p.PatternId)
select p;

虽然第一个更容易使用,但它确实存在一些问题。问题是您依赖 SQL Server 来处理链接服务器的性能,这是众所周知的糟糕之处。例如,考虑这个查询:

var results = from p in DataContext.Patterns
join r in DataContext.LinkedServerResults on p.PatternId equals r.PatternId
where r.userId = 10;

当您枚举此查询时,将发生以下情况(让我们分别调用普通服务器和链接服务器MyServerMyLinkedServer)

  1. MyServerMyLinkedServer 请求结果
  2. MyLinkedServer 将结果发送回 MyServer
  3. MyServer 获取这些结果,将它们连接到 Patterns 表中,并仅返回 Results.userId = 10 的结果

所以现在的问题是:什么时候完成过滤 - 在 MyServerMyLinkedServer 上?根据我的经验,对于这样一个简单的查询,通常会在 MyLinkedServer 上完成。但是,一旦查询变得更加复杂,您会突然发现 MyServer 正在从 MyLinkedServer 请求整个 结果表并进行过滤 < em>加入后!这会浪费带宽,而且如果结果表足够大,可能会将 50 毫秒的查询变成 50 秒的查询!

您可以使用存储过程修复性能不佳的跨服务器连接,但如果您执行大量复杂的跨服务器连接,您最终可能会为大部分查询编写存储过程,这需要大量工作并且会失败首先是使用 L2SQL 的目的(不必编写大量 SQL)

相比之下,以下代码将始终在包含结果表的服务器上执行过滤:

int[] patternIds = (from r in SessionDataProvider.Instance.ResultDataContext.Results
where r.userId = 10
select r.PatternId).ToArray();
var results = from p in PatternDataContext.Patterns
where patternIds.Contains(p.PatternId)
select p;

哪个最适合您的情况取决于您的最佳判断。


请注意,还有第三种可能的解决方案,我没有提到,因为它不是真正的程序员解决方案:您可以要求您的服务器管理员设置一个 replication task每天/每周/每月一次,将必要的数据从 MyLinkedServer 复制到 MyServer。这是一个选项,如果:

  • 您的程序可以处理来自 MyLinkedServer
  • 的稍微陈旧的数据
  • 您只需要读取而不是写入MyLinkedServer
  • MyLinkedServers 中您需要的表不是特别大
  • 您有可用的空间/带宽
  • 您的数据库管理员并不吝啬/懒惰

关于c# - 在 LINQ-to-SQL 中使用跨上下文连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5429469/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com