Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我如何介绍一个;或;运算符转换为linq查询联接_C#_Sql_Entity Framework_Linq_Linq To Sql - Fatal编程技术网

C# 我如何介绍一个;或;运算符转换为linq查询联接

C# 我如何介绍一个;或;运算符转换为linq查询联接,c#,sql,entity-framework,linq,linq-to-sql,C#,Sql,Entity Framework,Linq,Linq To Sql,将“or”运算符引入linq查询联接的语法是什么。它似乎不喜欢“| |”或“?我需要将一个外键与users表中两个可能的键连接起来 var thirdQuery = (from u in tbl_users join ua in tbl_userDocuments on (u.TransportUserID equals ua.fkDocumentID || u.WorkUserID equals ua.fkDocumentID) int

将“or”运算符引入linq查询联接的语法是什么。它似乎不喜欢“| |”或“?我需要将一个外键与users表中两个可能的键连接起来

var thirdQuery = (from u in tbl_users
join ua in tbl_userDocuments on (u.TransportUserID equals ua.fkDocumentID
                             || u.WorkUserID equals ua.fkDocumentID) into uaGroup
from uaTrans in uaGroup.DefaultIfEmpty()
join ul in tbl_user_logins on uaTrans.fkUserID equals ul.user_login_id_pk into ulGroup
如果没有或部分,则可以工作,但缺少额外的键

var thirdQuery = (from u in tbl_users
join ua in tbl_userDocuments on (u.TransportUserID equals ua.fkDocumentID) into uaGroup
from uaTrans in uaGroup.DefaultIfEmpty()
join ul in tbl_user_logins on uaTrans.fkUserID equals ul.user_login_id_pk into ulGroup

因此,您的数据库至少有两个表:
Users
UserDocuments
。每个
UserDocument
都有一个属性
fkDocumentId

虽然您并没有这样说,但在我看来,这是表
用户
中元素的外键。显然,这个外键有时指的是
User.TransportUserId
,有时指的是
User.WorkUserId

你确定要这个吗?如果
fkDocumentId
的值为10,它是指TransportId等于10的用户,还是指WorkUserId等于10的用户,或者两者都指

无论如何,如果您进行调查,您会发现您提供了两个密钥选择器:一个用于从用户中选择密钥,另一个用于从用户文档中选择密钥。当这两个键相等时,ResultSelector参数用于构造联接元素

问题在于“平等”一词。您必须确保您选择了密钥,并提供了一个IEqualityComparer,以便将密钥视为相等

另一个更简单的方法是创建一个新的连接扩展方法

IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult> Join(
    this IEnumerable<TSource> outer,
    IEnumerable<TInner> inner,
    Func<TOuter, TKey> outerKeySelector1,
    Func<TOuter, TKey> outerKeySelector2,
    Func<TInner, TKey> innerKeySelector,
    Func<TOuter, TInner, TResult> resultSelector)
{
    // make two lookup tables from Outer: one for key1 and one for key2:
    var lookup1 = outer.ToLookup( outerElement => outerKeySelector1(outerElement));
    var lookup2 = outer.ToLookup( outerElement => outerKeySelector2(outerElement));

    // so if you have a TKey from the innerKeySelector, you can find if it matches key1 or key2
    foreach (TInner innerElement in inner)
    {
        TKey innerKey = innerKeySelector(innerElement)
        var matchingElementsKey1 = lookup1[innerKey];
        var matchineElementsKey2 = lookup2[innerKey];
        var allmatchingElements = matchingElementsKey1.Concat(matchingElementsKey2);

        foreach(var matchingElement in allMatchingElements)
        {
            TResult result = resultSelector(matchingElement, innerElement);
            yield return result;
        }
    }
}

请参见my-基本上,您必须执行交叉联接,并将OR条件放入
中的
位置。您确定要这样做吗?-别无选择,这是我们团队采用的非常大的遗留应用程序。fkDocumentId是指TransportId还是WorkUserId?它可以是或空。谢谢你花时间帮忙。
var result = tblUsers.Join(tblUserDocuments,
    user => user.TransportUserId,           // select outerKey1
    user => user.WorkUserId,                // select outerKey2
    document => document.fkDocumentId,      // select innerKey

    // when inner key matches either outerKey1, or outerKey2, create one new object:
    (user, document) => new
    {
        // Select the user documents that you want:
        UserId = user.Id,
        Name = user.Name,
        ...

        // Select the document properties that you want:
        DocumentId = document.Id,
        Author = document.Author,
        PublishedDate = document.Date,
        ...
    })