【问题标题】:Querying n:m-Relationships with LINQ使用 LINQ 查询 n:m 关系
【发布时间】:2012-07-11 17:38:53
【问题描述】:

我得到了这三个表的 n:m-Relationship:

现在我想查询所有附有选定Characteristics 列表的Activities。

我的查询:

e.QueryableSource = _dataContext.Activities.Where(ac => 
                ac.UserId == _userId && 
                ac.ResubmissionDate <= EntityFunctions.TruncateTime(_to) && 
                ac.Priority <= (int)_prio && 
                ac.CompletedDate == null && 
                ac.Characteristics.Contains(CharacFilter));

遗憾的是,这不起作用,因为 ac.Characteristics.Contains() 需要 ActivityCharacteristics 类型的项目,而不是 Characteristic 类型的项目

我怎样才能做到这一点?

一个侧节点:我不想要排他过滤,比如当我在CharacFilter 中指定三个特征时,我想查询可能附加了这三个特征之一(不一定全部)的每个活动。

编辑: CharacFilter 是 private IEnumerable&lt;int&gt; CharacFilter { get; set; } 它是从我选择这些特征并将它们保存在 View-Variable public List&lt;Characteristic&gt; SelectedCharacteristics { get; set; }

的视图中填充的

我的任务:

        var view = new AssignCharacteristicsView();
        view.ShowDialog();

        if (view.SelectedCharacteristics != null)
        {
            CharacFilter = view.SelectedCharacteristics.Select(cf => cf.Id);
        }

`

【问题讨论】:

    标签: c# sql-server linq entity-framework-4.3


    【解决方案1】:

    如果CharacFilter 是IEnumerable&lt;Characteristics&gt;,你可以试试:

    IEnumerable<int> charaFilters = CharacFilter.Select(cf => cf.Id);
    
    e.QueryableSource = _dataContext.Activities.Where(ac => 
        ac.UserId == _userId && 
        ac.ResubmissionDate <= EntityFunctions.TruncateTime(_to) && 
        ac.Priority <= (int)_prio && 
        ac.CompletedDate == null &&
        ac.Characteristics.Any(acc => characFilters.Contains(acc.CharacteristicId)));
    

    (acc 的类型为 ActivityCharacteristics。)

    并且Activity.Characteristics 应该真正具有名称Activity.ActivityCharacteristics,就像您在Characteristics 实体中命名它一样。否则会很混乱。

    编辑

    关于你的例外

    无法创建类型的常量值 'System.Collections.Generic.IEnumerable'1'

    如果CharacFilter 是null 你确实会得到这个异常,因为null 是一个EF 无法创建的常量值。它不会抛出NullReferenceException,因为您在表达式中使用了CharacFilter。根据您在问题中编辑的代码CharacFilter 可能是null 如果view.SelectedCharacteristics 是null。

    要解决问题,您必须根据view.SelectedCharacteristics == null 是指应用程序中的所有 特征还是无 来捕获null 的情况。如果它意味着 none 我建议实例化一个空列表:

    if (view.SelectedCharacteristics != null)
    {
        CharacFilter = view.SelectedCharacteristics.Select(cf => cf.Id);
    }
    else
    {
        CharacFilter = new List<int>();
    }
    

    如果这意味着您可以尝试所有特征:

    // ...
    ac.Characteristics.Any(acc => (characFilters != null
        ? characFilters.Contains(acc.CharacteristicId)
        : true)));
    

    编辑 2

    最后一个选项抛出相同的异常(这并不奇怪,因为要将CharacFilter 与null 进行比较,必须再次创建一个常量值)。替代方案(如果CharacFilter 是null,则省略最后一个Where 子句):

    ObjectQuery<Activity> query = _dataContext.Activities.Where(ac => 
        ac.UserId == _userId && 
        ac.ResubmissionDate <= EntityFunctions.TruncateTime(_to) && 
        ac.Priority <= (int)_prio && 
        ac.CompletedDate == null);
    
    if (characFilters != null)
    {
        query = query.Where(ac => ac.Characteristics
                         .Any(acc => characFilters.Contains(acc.CharacteristicId)));
    }
    
    e.QueryableSource = query;
    

    【讨论】:

    • 谢谢,我再次将其重命名为Activity.ActivityCharacteristics。由于characFilter 的类型为IEnumerable&lt;Characteristics&gt; 而不是IEnumerable&lt;int&gt;,因此我将最后一行更改为:ac.ActivityCharacteristics.Any(acc =&gt; CharacFilter.Contains(acc.Characteristic)));
    • 好的,我已经运行代码并得到以下异常:Unable to create a constant value of type 'System.Collections.Generic.List1'.`
    • @SeToY:那是因为你的改变。你为什么不用我的第一行?
    • 不,即使没有我的更改和您对 int-Values 的原始查询,它也会发生,而是改为 Unable to create a constant value of type 'System.Collections.Generic.IEnumerable'.。
    • @SeToY:我已经测试过了,它可以工作。一定有什么不同。如果我使用您的代码,我不会收到异常“无法创建类型为 'System.Collections.Generic.List 1' 的常量值”,而是“无法创建常量” 'Characteristics'" 类型的值,这是我所期望的。我们可能不是在谈论相同的代码。您问题中的CharacFilter 到底是什么? List&lt;Characteristics&gt;?
    猜你喜欢
    • 2017-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-03
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    相关资源
    最近更新 更多