Naw*_*waz 10 c# linq database datacontext linq-to-sql
最初我使用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;
Run Code Online (Sandbox Code Playgroud)
当我执行它,并result
在QuickWatch中看到它时,它显示了以下消息:
查询包含对在不同数据上下文中定义的项的引用
在谷歌搜索,我在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;
Run Code Online (Sandbox Code Playgroud)
此查询使用以下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;
}
Run Code Online (Sandbox Code Playgroud)
但即便采用这种方法也无法解决问题.我仍然在QuickWatch中收到此消息...:
查询包含对在不同数据上下文中定义的项的引用
解决这个问题的任何方法?除了解决方案之外,我还想知道为什么问题仍然存在,以及新解决方案如何将其删除,以便下次我可以自己解决这些问题.顺便说一句,我是LINQ的新手.
我以前必须这样做,有两种方法可以做到这一点.
第一种是将所有服务器移动到单个上下文中.您可以通过将LINQ-to-SQL指向单个服务器,然后在该服务器中为所有其他服务器创建链接服务器.然后,您只需为其他服务器感兴趣的表创建视图,并将这些视图添加到您的上下文中.
第二种是通过从一个上下文中提取数据,并仅使用您需要连接到另一个上下文的属性来自己手动执行连接.例如,
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;
Run Code Online (Sandbox Code Playgroud)
虽然第一个更易于使用,但它确实存在一些问题.问题是你依赖SQL Server来实现链接服务器的性能,这是非常糟糕的.例如,考虑以下查询:
var results = from p in DataContext.Patterns
join r in DataContext.LinkedServerResults on p.PatternId equals r.PatternId
where r.userId = 10;
Run Code Online (Sandbox Code Playgroud)
当您枚举此查询时,将发生以下情况(让我们分别调用普通服务器MyServer
和链接服务器MyLinkedServer
)
MyServer
要求MyLinkedServer
结果MyLinkedServer
将结果发送回 MyServer
MyServer
获取这些结果,将它们连接到Patterns表,并仅返回Results.userId = 10的结果所以现在的问题是:过滤何时完成 - 开启MyServer
或MyLinkedServer
?根据我的经验,对于这样一个简单的查询,它通常会在上面完成MyLinkedServer
.但是,一旦查询变得更复杂,您将突然发现从MyServer
请求整个结果表MyLinkedServer
并在加入后进行过滤!这会浪费带宽,如果结果表足够大,可以将50ms查询转换为50秒查询!
您可以使用存储过程修复不可信的跨服务器连接,但是如果您执行大量复杂的跨服务器连接,您可能最终会为大多数查询编写存储过程,这是很多工作并且会破坏部分目的首先使用L2SQL (不必编写大量SQL).
相比之下,以下代码将始终在包含Results表的服务器上执行过滤:
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;
Run Code Online (Sandbox Code Playgroud)
哪种情况最适合您的情况取决于您的最佳判断.
请注意,是我没有提到第三个潜在的解决方案,因为它是不是一个真正的程序员的解决方案:你可以问你的服务器管理员来设置一个复制任务从复制所需要的数据MyLinkedServer
,以MyServer
每天一次/周/月.这只是一个选项,如果:
MyLinkedServer
MyLinkedServer
MyLinkedServers
不是很庞大 归档时间: |
|
查看次数: |
4130 次 |
最近记录: |