Linq to sql LINQ AssociateWith用于生成左连接而不是内部连接的数据上下文

Linq to sql LINQ AssociateWith用于生成左连接而不是内部连接的数据上下文,linq-to-sql,Linq To Sql,我正在尝试为我的上下文创建一个“AssociateWith”数据加载选项,以筛选当前用户有权访问的行。我的简单数据模型如下所示: 表格 用户权限 主键:ID FK:RelatedUserID可为空 FK:RelatedItemID不可为空 用户 主键:ID 项目 主键:ID FK:RelatedCategoryID不可为空 类别 主键:ID 在我的datacontext中,我尝试执行以下操作: //dbContext is my LINQ context //current_user_id i

我正在尝试为我的上下文创建一个“AssociateWith”数据加载选项,以筛选当前用户有权访问的行。我的简单数据模型如下所示:

表格
用户权限
主键:ID
FK:RelatedUserID可为空
FK:RelatedItemID不可为空

用户
主键:ID

项目
主键:ID
FK:RelatedCategoryID不可为空

类别 主键:ID

在我的datacontext中,我尝试执行以下操作:

//dbContext is my LINQ context 
//current_user_id is the id of my current logged in user 
var dlo = new DataLoadOptions();
//issue->UsersPermissions is one->many relationship
// if I omit this LoadWith line, no associatewith filter
// is created in the generated sql code
dlo.LoadWith<Items>(i=>i.UserPermissions); 

dlo.AssociateWith<Items>(i=>
i.UserPermissions.Where(p=>
p.RelatedUserID.HasValue && p.RelatedUserID.Value == current_users_id));
dbContext.LoadOptions = dlo;
如何强制内部联接而不是左外部联接?我是否在后端错误地建模了我的关系

谢谢你的帮助


MMAS

LINQ to SQL生成左外部联接的原因很简单,因为
UserPermissions.RelatedUserID
列可为空。底层LINQ提供程序不够“智能”,无法进一步优化该查询以实现简单的内部连接。我认为你对此无能为力。

这正是我所担心的——如果你好奇的话,它之所以可以为空是因为该表最终将引用另一个FK(我们称之为RelatedUsersCompanyID)这也是可以为空的,在实践中,将始终提供RelatedUserID或RelatedUsersCompanyID。其思想是,我们可以添加一行,允许特定公司中的任何用户访问同一项目,而不是为每个有权访问某个项目的用户在用户表中添加一行。关于如何使用AssociateWith方法获得这种数据模型所需的行为,有什么好主意吗?:)你不能把
UserPermissions
表放在用户表和公司表中吗?通常应尽量减少数据库中可为空的列的数量。此外,为什么要使用
Associatewith
来构建过滤器?有什么理由不只是以“常规”的方式(在LINQ查询中)进行过滤吗?我希望通过将过滤器构建到datacontext中使开发人员更容易进行过滤,因为我们几乎总是根据权限进行过滤。不幸的是,我不知道为什么,即使我在permissions表上设置了RelatedItemID,我仍然会生成一个左外部联接。不知道为什么在这种情况下…为什么这对你来说是个问题?使用
AssociateWith
似乎是我以前从未想到过的一种有趣的方法。我不确定你能做所有你需要的过滤。我经常为此编写扩展方法。例如:
GetForUser(这个IQueryable p,int userId)
。这允许您编写
db.UserPermissions.GetForUser(id)
。尽管如此,您的方法还是很有趣的。左侧外部联接最终返回了所有无法联接的行的列中的空行。一个内部连接将消除这些行,这正是我所希望的。。。
SELECT [t0].[ID], [t1].[ID] AS [ID2], [t1].[RelatedUserID], [t1].[RelatedItemID] 
(SELECT COUNT(*)
FROM [dbo].[UserPermissions] AS [t2]
WHERE (([t2].[RelatedUserID] = @p0)) AND ([t2].[RelatedItemID] = [t0].[ID])
) AS [value]
FROM [dbo].[Items] AS [t0]
LEFT OUTER JOIN [dbo].[UserPermissions] AS [t1] ON ([t1].[RelatedUserID] = @p0) 
AND     
([t1].[RelatedItemID] = [t0].[ID])
ORDER BY [t0].[ID], [t1].[ID]