LightSwitch PreprocessQuery不会过滤

时间:2017-02-08 17:31:26

标签: c# linq visual-studio-lightswitch

    partial void PartsInProject_PreprocessQuery(int? projectId, ref IQueryable<Part> query)
    {

        query = (from projectPart in ProjectParts.GetQuery().Execute()
                 where projectPart.Project.Id == projectId
                 select projectPart.Part).AsQueryable();

        var test = query.ToList();
    }

这段代码编译似乎有用...我的意思是当我在var测试中设置断点并检查它时,它具有正确的(已过滤的)项目但是当我在屏幕上查看结果时它会显示整个列出没有应用过滤。

应该这么简单:

    partial void PartsInProject_PreprocessQuery(int? projectId, ref IQueryable<Part> query)
    {
        IEnumerable<int> projectPartIds = new[] {1, 2, 3};

        query = from part in query
                where projectPartIds.Contains(part.Id)
                select part;
    }

但是当我这样做时,LightSwitch会抛出一个错误:

未实施内部异常消息:方法&#39;包含&#39;不受支持。

另一方面,这很有效,但对我没有帮助:

    partial void PartsInProject_PreprocessQuery(int? projectId, ref IQueryable<Part> query)
    {
        query = from part in query
                where (part.Id == 1 || part.Id == 2 || part.Id == 3)
                select part;
    }

编辑1:

根据建议我也尝试过这样:

    partial void PartsInProject_PreprocessQuery(int? projectId, ref IQueryable<Part> query)
    {
        var projectPartIds = new List<int> {1, 2, 3};

        query = from part in query
                where projectPartIds.Contains(part.Id)
                select part;
    }

但后来我收到了这个错误: 未实现内部异常消息:表达式值(System.Collections.Generic.List`1 [System.Int32])。Conta ins([10007] .Id)不受支持

编辑2:

以下是我尝试的事项列表及其各自的错误:

    partial void PartsInProject_PreprocessQuery(int? projectId, ref IQueryable<Part> query)
    {
        var projectPartIds = new List<int> {1, 2, 3};

        query = from part in query
                where projectPartIds.All(x => x != part.Id)
                select part;
    }

错误:当MaxProtocolVersion低于3.0时,不支持All方法

    partial void PartsInProject_PreprocessQuery(int? projectId, ref IQueryable<Part> query)
    {
        var projectPartIds = new[] { 1, 2, 3 };
        query = query.Where(x => projectPartIds.Contains(x.Id));
    }

错误:该方法包含不受支持的

    //I forgot to save the code for this example...

错误:不支持加入

    partial void PartsInProject_PreprocessQuery(int? projectId, ref IQueryable<Part> query)
    {
        var projectPartIds = new List<int> { 1, 2, 3 };
        IQueryable<Part> qTest = null;
        foreach (var partId in projectPartIds)
        {
            if (qTest == null)
            {
                qTest = from part in query
                        where part.Id != partId
                        select part;
            }
            else
            {
                qTest = (from part in query
                         where part.Id != partId
                         select part)
                    .Union(
                        from part in qTest
                        select part
                    );
            }
        }
        query = qTest;
    }

错误:不支持联盟

    partial void PartsInProject_PreprocessQuery(int? projectId, ref IQueryable<Part> query)
    {
        var q1 = from part in query
                 where part.Id == 1
                 select part;

        var q2 = from part in query
                 where part.Id == 2
                 select part;

        query = q1.Concat(q2);
    }

错误:不支持Concat方法

    partial void PartsInProject_PreprocessQuery(int? projectId, ref IQueryable<Part> query)
    {
        var temp = this.ProjectParts.GetQuery().Execute().AsQueryable();
        query = from p in query
                from pp in temp
                where pp.Part.Id == p.Id
                select p;
    }

错误:System.Linq.IQueryable [LightSwitchApplication.ProjectPart]类型的表达式不能用于返回类型System.Collections.Generic.IEnumerable [LightSwitchApplication.Implementation.ProjectPart]

    partial void PartsInProject_PreprocessQuery(int? projectId, ref IQueryable<Part> query)
    {
        var projectPartIds = (from pp in ProjectParts.GetQuery().Execute()
                              where pp.Project.Id == projectId.Value
                              select pp.Part).AsQueryable();
        query = query.Intersect(projectPartIds);
    }

错误:不支持表达式(相交)。参数类型不匹配

    partial void PartsInProject_PreprocessQuery(int? projectId, ref IQueryable<Part> query)
    {
        var projectPartIds = (from pp in ProjectParts.GetQuery().Execute()
                              where pp.Project.Id == projectId
                              select pp.Part.Id).ToList();

        var tempQuery = query;
        foreach (var partId in projectPartIds)
        {
            tempQuery = from p in tempQuery
                        where p.Id != partId
                        select p;
        }

        query = query.Except(tempQuery);
    }

错误:不支持方法

最终笔记(更新2):

我确实找到了一件有用的东西,它对于星期五的演示来说已经足够好了,我只有10个零件,但这是不可接受的,因为我不相信它能够扩展到我有500k零件。这是代码,以防它给任何人一个我没想过的想法:

    partial void PartsInProject_PreprocessQuery(int? projectId, ref IQueryable<Part> query)
    {
        var projectPartIds = (from pp in ProjectParts.GetQuery().Execute()
                              where pp.Project.Id == projectId
                              select pp.Part.Id).ToList();

        var allPartIds = (from p in Parts.GetQuery().Execute()
                          select p.Id).ToList();

        var nonProjectPartIds = allPartIds.Except(projectPartIds).ToList();

        foreach (var partId in nonProjectPartIds)
        {
            query = from p in query
                    where p.Id != partId
                    select p;
        }
    }

1 个答案:

答案 0 :(得分:0)

要使用ContainsprojectPartIds定义为List<int>。 这编译并运行OK:

public static void test4()
{
    List<Part> parts = new List<Part>();
    parts.Add(new Part() { Id = 1 });
    parts.Add(new Part() { Id = 2 });
    parts.Add(new Part() { Id = 10 });
    parts.Add(new Part() { Id = 11 });
    var query = parts.AsQueryable();

    List<int> projectPartIds = new List<int>(new []{ 1, 2, 3 });

    var results  = from part in query
            where projectPartIds.Contains(part.Id)
            select part;
    foreach (var res in results)
    {
        Console.WriteLine("Result="+res.Id);
    }
}
public class Part
{
    public int Id;
}

刚刚测试了它,这里是输出,没有例外:

enter image description here

<强> EDIT2

即便如此:

static void Main(string[] args)
{
    test5();
    Console.ReadLine();
}

public static void test5()
{
    List<Part> parts = new List<Part>();
    parts.Add(new Part() { Id = 1 });
    parts.Add(new Part() { Id = 2 });
    parts.Add(new Part() { Id = 10 });
    parts.Add(new Part() { Id = 11 });
    var query = parts.AsQueryable();

    test4(ref query);
}
public static void test4(ref IQueryable<Part> query)
{

    List<int> projectPartIds = new List<int>{ 1, 2, 3 };

    query  = from part in query
            where projectPartIds.Contains(part.Id)
            select part;

    foreach (var res in query)
    {
        Console.WriteLine("Result="+res.Id);
    }
}

与上面的输出相同。

编辑3

我怀疑您的Query提供商(ProjectParts.GetQuery().Execute()中的实施)不支持List<>.Contains,在这种情况下,最好是ToList()您的查询结果,然后提取准备好结果到另一个查询对象然后使用它。否则修改原始查询就会遇到问题:

static void Main(string[] args)
{
    test5();
    Console.ReadLine();
}

public static void test5()
{
    List<Part> parts = new List<Part>();
    parts.Add(new Part() { Id = 1 });
    parts.Add(new Part() { Id = 2 });
    parts.Add(new Part() { Id = 10 });
    parts.Add(new Part() { Id = 11 });
    var query = parts.AsQueryable();

    IQueryable<Part> preparedQuery;
    test6(query, out preparedQuery);  // results are output into preparedQuery

    foreach (var res in preparedQuery)
    {
        Console.WriteLine("Result=" + res.Id);
    }
}

public static void test6(IQueryable<Part> origQuery, out IQueryable<Part> preparedQuery)
{

    List<int> projectPartIds = new List<int> { 1, 2, 3 };
    var queryList = origQuery.ToList(); // convert to list to get a working Contains

    preparedQuery = (from part in queryList
            where projectPartIds.Contains(part.Id)
            select part).AsQueryable();

}