Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.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 to SQL Concat/Union在自定义类上不起作用_C#_.net_Linq_Linq To Sql_Linq To Entities - Fatal编程技术网

C# Linq to SQL Concat/Union在自定义类上不起作用

C# Linq to SQL Concat/Union在自定义类上不起作用,c#,.net,linq,linq-to-sql,linq-to-entities,C#,.net,Linq,Linq To Sql,Linq To Entities,Linq to SQL Concat/Union在自定义类上不起作用 自定义类 工会: 执行上述查询时,我得到以下错误: “Distinct”操作无法应用于集合 指定参数的结果类型。\r\n参数名称:参数 海螺 执行上述查询时,我得到以下错误: {不支持嵌套查询。Operation1='UnionAll' 操作2='MultiStreamNest'} 最后,我要做的是,如果Users表的Auth字段为true,则我希望AuthTrue表中的数据存储在列表字段中,如果Users表的Auth字段为f

Linq to SQL Concat/Union在自定义类上不起作用

自定义类

工会:

执行上述查询时,我得到以下错误:

“Distinct”操作无法应用于集合 指定参数的结果类型。\r\n参数名称:参数

海螺

执行上述查询时,我得到以下错误:

{不支持嵌套查询。Operation1='UnionAll' 操作2='MultiStreamNest'}

最后,我要做的是,如果Users表的Auth字段为true,则我希望AuthTrue表中的数据存储在列表字段中,如果Users表的Auth字段为false,则我希望AuthFalse表中的数据存储在列表字段中

我希望所有这些都能在单个查询或最多2到3个查询中完成


谢谢。

您应该像这样重写您的Concat尝试: 1.从用户开始 2.然后对AuthFalse和AuthTrue执行两个左连接 3.添加按用户进行筛选。验证字段和正确的右匹配 4.请选择与user.Id、user.LastName、user.FirstName+AuthFalse匹配或AuthTrue匹配的匿名类。在这个阶段,可查询的必须由可计算的浇铸而成 5.然后剩下的就是正确的分组+选择

以下是完整单元测试的步骤:

public class CustomClass
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public List<CustomAccesses> Accesses { get; set; }
    }

    public class CustomAccesses
    {
        public int Rights { get; set; }
    }


    public class Accesses
    {
        public Guid ID { get; set; }
        public Guid UID { get; set; }
        public int Rights { get; set; }
    }

    public class User
    {
        public Guid ID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public bool Auth { get; set; }
    }

    [TestFixture]
    public class QueryTests
    {
        private static readonly User TrueUser = new User
        {
            ID = Guid.NewGuid(),
            FirstName = "TrueFirstName",
            LastName = "TrueLastName",
            Auth = true
        };

        private static readonly User FalseUser = new User
        {
            ID = Guid.NewGuid(),
            FirstName = "FalseFirstName",
            LastName = "FalseLastName",
            Auth = false
        };

        private static readonly User[] DbUsersMock =
        {
            TrueUser,
            FalseUser
        };

        private static readonly Accesses[] DbAuthTrueMock =
        {
            new Accesses
            {
                ID = Guid.NewGuid(),
                UID = TrueUser.ID,
                Rights = 1
            },
            new Accesses
            {
                ID = Guid.NewGuid(),
                UID = TrueUser.ID,
                Rights = 2
            }
        };

        private static readonly Accesses[] DbAuthFalseMock =
        {
            new Accesses
            {
                ID = Guid.NewGuid(),
                UID = FalseUser.ID,
                Rights = -1
            },
            new Accesses
            {
                ID = Guid.NewGuid(),
                UID = FalseUser.ID,
                Rights = -2
            }
        };

        [Test]
        public void Test()
        {
            var users = DbUsersMock.AsQueryable();

            var authTrue = DbAuthTrueMock.AsQueryable();

            var authFalse = DbAuthFalseMock.AsQueryable();


            var result = users
                .GroupJoin(
                    authTrue,
                    u => u.ID,
                    ta => ta.UID,
                    (user, accesses) => new
                    {
                        user,
                        accesses = accesses.DefaultIfEmpty()
                    }
                )
                .SelectMany(
                    ua => ua
                        .accesses
                        .Select(
                            trueAccess => new
                            {
                                ua.user,
                                trueAccess
                            }
                        )
                )
                .GroupJoin(
                    authFalse,
                    ua => ua.user.ID,
                    fa => fa.UID,
                    (userAccess, accesses) => new
                    {
                        userAccess,
                        accesses = accesses.DefaultIfEmpty()
                    }
                )
                .SelectMany(
                    uaa => uaa
                        .accesses
                        .Select(
                            falseAccess => new
                            {
                                uaa.userAccess.user,
                                uaa.userAccess.trueAccess,
                                falseAccess
                            }
                        )
                )
                .Where(
                    uaa => uaa.user.Auth
                        ? uaa.trueAccess != null
                        : uaa.falseAccess != null
                )
                .Select(
                    uaa => new
                    {
                        uaa.user.ID,
                        uaa.user.FirstName,
                        uaa.user.LastName,
                        AccessID = uaa.user.Auth
                            ? uaa.trueAccess.ID
                            : uaa.falseAccess.ID,
                        Rights = uaa.user.Auth
                            ? uaa.trueAccess.Rights
                            : uaa.falseAccess.Rights
                    }
                )
                .OrderBy(uaa => uaa.ID)
                .AsEnumerable()
                .GroupBy(uaa => uaa.ID)
                .Select(
                    g => new CustomClass
                    {
                        FirstName = g.First().FirstName,
                        LastName = g.First().LastName,
                        Accesses = g
                            .GroupBy(uaa => uaa.AccessID)
                            .Select(
                                uaa => new CustomAccesses
                                {
                                    Rights = uaa.First().Rights
                                }
                            )
                            .ToList()
                    }
                )
                .ToArray();

            Assert.That(result.Length, Is.EqualTo(DbUsersMock.Length));
        }
    }

你可以用很多方法来做。一个简单的方法是: 拿两张清单,一张是正确的,另一张是错误的。然后在结果列表中使用ADDRANGE方法。 此方法ADDRANGE仅在处理列表时有效

例如:

var listTrue = ctx.Users.Where(...).Select(s=> new CustomClass{...}).ToList();
var listFalse = ctx.Users.Where(...).Select(s=> new CustomClass{...}).ToList();
var result = new List<CustomClass>();
result.AddRange(listTrue);
result.AddRange(listFalse);
return result;

可能您应该像这样重写您的Concat尝试:从用户开始,然后对AuthFalse和AuthTrue执行两个左连接添加按用户进行筛选。Auth字段和正确的右匹配,选择具有user.Id、user.LastName、user.FirstName+AuthFalse匹配或AuthTrue匹配的匿名类。在这一阶段,可查询必须通过铸造到可计算,然后剩下的就是正确的分组+选择。@Vitaliykalin,谢谢,你能提供一些代码片段吗?因为我不明白你想说什么来实现。谢谢,你使用了AsEnumerable方法来触发查询,但我不想触发查询,因为在那之后我必须添加搜索关键字条件和排序功能。所有这些我都想在数据库上而不是内存中完成。我已经将一个numerable放在LinqToSql能够正确处理您的需求的地方。若你们的描述是不完整的,那个么你们应该准备好不完整的解决方案。实际上,这段代码是我作为注释发布的解释片段。我将复制粘贴我的评论作为回答。
IQueryable<CustomClass> objQuery = context.Users       
    .Where(W => W.Auth == true)
    .Select(S => new CustomClass()
    {
        FirstName = S.FirstName,
        LastName = S.LastName,
        Accesses = context.AuthFalse
                    .Where(W => W.UID = S.ID)
                    .Select(S1 => new Accesses()
                    {
                        AccessesID = S1.AccessesID,                                                
                    })
                    .ToList(),
    })
    .Concat(context.Users    
        .Where(W => W.Auth == true)                            
        .Select(S => new CustomClass()
        {
            FirstName = S.FirstName,
            LastName = S.LastName,
            Accesses = context.AuthTrue
                        .Where(W => W.UID = S.ID)
                        .Select(S1 => new Accesses()
                        {
                            AccessesID = S1.AccessesID,                                                
                        })
                        .ToList(),
        })
    );
public class CustomClass
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public List<CustomAccesses> Accesses { get; set; }
    }

    public class CustomAccesses
    {
        public int Rights { get; set; }
    }


    public class Accesses
    {
        public Guid ID { get; set; }
        public Guid UID { get; set; }
        public int Rights { get; set; }
    }

    public class User
    {
        public Guid ID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public bool Auth { get; set; }
    }

    [TestFixture]
    public class QueryTests
    {
        private static readonly User TrueUser = new User
        {
            ID = Guid.NewGuid(),
            FirstName = "TrueFirstName",
            LastName = "TrueLastName",
            Auth = true
        };

        private static readonly User FalseUser = new User
        {
            ID = Guid.NewGuid(),
            FirstName = "FalseFirstName",
            LastName = "FalseLastName",
            Auth = false
        };

        private static readonly User[] DbUsersMock =
        {
            TrueUser,
            FalseUser
        };

        private static readonly Accesses[] DbAuthTrueMock =
        {
            new Accesses
            {
                ID = Guid.NewGuid(),
                UID = TrueUser.ID,
                Rights = 1
            },
            new Accesses
            {
                ID = Guid.NewGuid(),
                UID = TrueUser.ID,
                Rights = 2
            }
        };

        private static readonly Accesses[] DbAuthFalseMock =
        {
            new Accesses
            {
                ID = Guid.NewGuid(),
                UID = FalseUser.ID,
                Rights = -1
            },
            new Accesses
            {
                ID = Guid.NewGuid(),
                UID = FalseUser.ID,
                Rights = -2
            }
        };

        [Test]
        public void Test()
        {
            var users = DbUsersMock.AsQueryable();

            var authTrue = DbAuthTrueMock.AsQueryable();

            var authFalse = DbAuthFalseMock.AsQueryable();


            var result = users
                .GroupJoin(
                    authTrue,
                    u => u.ID,
                    ta => ta.UID,
                    (user, accesses) => new
                    {
                        user,
                        accesses = accesses.DefaultIfEmpty()
                    }
                )
                .SelectMany(
                    ua => ua
                        .accesses
                        .Select(
                            trueAccess => new
                            {
                                ua.user,
                                trueAccess
                            }
                        )
                )
                .GroupJoin(
                    authFalse,
                    ua => ua.user.ID,
                    fa => fa.UID,
                    (userAccess, accesses) => new
                    {
                        userAccess,
                        accesses = accesses.DefaultIfEmpty()
                    }
                )
                .SelectMany(
                    uaa => uaa
                        .accesses
                        .Select(
                            falseAccess => new
                            {
                                uaa.userAccess.user,
                                uaa.userAccess.trueAccess,
                                falseAccess
                            }
                        )
                )
                .Where(
                    uaa => uaa.user.Auth
                        ? uaa.trueAccess != null
                        : uaa.falseAccess != null
                )
                .Select(
                    uaa => new
                    {
                        uaa.user.ID,
                        uaa.user.FirstName,
                        uaa.user.LastName,
                        AccessID = uaa.user.Auth
                            ? uaa.trueAccess.ID
                            : uaa.falseAccess.ID,
                        Rights = uaa.user.Auth
                            ? uaa.trueAccess.Rights
                            : uaa.falseAccess.Rights
                    }
                )
                .OrderBy(uaa => uaa.ID)
                .AsEnumerable()
                .GroupBy(uaa => uaa.ID)
                .Select(
                    g => new CustomClass
                    {
                        FirstName = g.First().FirstName,
                        LastName = g.First().LastName,
                        Accesses = g
                            .GroupBy(uaa => uaa.AccessID)
                            .Select(
                                uaa => new CustomAccesses
                                {
                                    Rights = uaa.First().Rights
                                }
                            )
                            .ToList()
                    }
                )
                .ToArray();

            Assert.That(result.Length, Is.EqualTo(DbUsersMock.Length));
        }
    }
var listTrue = ctx.Users.Where(...).Select(s=> new CustomClass{...}).ToList();
var listFalse = ctx.Users.Where(...).Select(s=> new CustomClass{...}).ToList();
var result = new List<CustomClass>();
result.AddRange(listTrue);
result.AddRange(listFalse);
return result;