查询n:m与LINQ的关系

时间:2012-07-11 17:38:54

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

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

Database Model

现在,我想查询所有Activities,其中包含所选的Characteristics列表。

我的查询:

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中指定三个特征时,我想查询可能具有这三个特征之一的所有活动(不一定都是全部)附接。

编辑: CharacFilterprivate IEnumerable<int> CharacFilter { get; set; } 它是从我选择这些特征的视图中填充的,并将它们保存在视图变量public List<Characteristic> SelectedCharacteristics { get; set; }

我的任务:

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

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

`

1 个答案:

答案 0 :(得分:4)

如果CharacFilterIEnumerable<Characteristics>,您可以尝试:

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'

如果CharacFilternull,您确实会收到此异常,因为null是EF无法创建的常量值。它不会抛出NullReferenceException,因为您在表达式中使用CharacFilter。如果CharacFilter null view.SelectedCharacteristics null,则null中的编辑代码可能为view.SelectedCharacteristics == null

要解决此问题,您必须抓住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))); 是否意味着所有特征或应用程序中 none 。如果它意味着 none 我会建议实例化一个空列表:

CharacFilter

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

null

修改2

最后一个选项会抛出相同的异常(这并不奇怪,因为要将WhereCharacFilter进行比较,必须再次创建一个常量值。替代方案(如果nullObjectQuery<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; ,则省略最后{{1}}条款):

{{1}}