2

POCO

public class Widget
{
    public Guid Id { get; set; }
    // other properties...
    public Guid WidgetTypeId { get; set; }
    public WidgetType WidgetType { get; set; }
}

public class WidgetType
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public List<Widget> Widgets { get; set; }
}

语境

public class WidgetContext : DbContext
{
    // ...
    public DbSet<WidgetType> WidgetTypes { get; set; }
    public DbSet<Widget> Widgets { get; set; }
    // ...
}

商业模式:

public class WidgetSearchModel
{
    public List<WidgetTypeListItem> SelectedWidgetTypes { get; set; } 

    // ... constructors... one that fills out the selection list and gets passed to a view

    public List<Widget> GetWidgets()
    {
        using (var context = new WidgetContext())
        {
            var widgets =
                (from d in context.Widgets
                 join t in SelectedWidgetTypes on d.WidgetTypeId equals t.Id
                 where t.Selected
                 // other search criteria
                 select d).ToList();

            return widgets;
        }
    }
}

public class WidgetTypeListItem
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public bool Selected { get; set; }
}

目的是允许用户为搜索操作选择多个小部件类型,并将具有所选类型的所有小部件返回到视图。

我希望 GetWidgets 方法能够工作,但显然它不会,因为 Linq to SQL 对我的内存选择列表一无所知。在过去,我会通过遍历选择列表手动生成 SQL。在这种情况下,有没有办法让 Linq to SQL 生成一些不错的 SQL?当然,我可以拉入所有小部件,然后根据选择列表进行选择,但根据表格的大小,这可能真的效率低下。我宁愿为我将逻辑转换为 SQL。任何想法如何做到这一点?

4

2 回答 2

2

您仍然可以使用内存列表的Contains方法:

var idsToGet = SelectedWidgetTypes.Select(t=>t.Id).ToList();
var widgets =
            (from d in context.Widgets
             where idsToGet.Contains(d.WidgetTypeId)
             // other search criteria
             select d).ToList();

这将产生类似的东西:

WHERE WidgetTypeId IN (1, 2, 3..)
于 2013-11-05T15:58:44.093 回答
2

只需选择小部件类型 ID 并检查小部件类型 ID 是否在该列表中(这将生成 SQL IN 运算符):

using (var context = new WidgetContext())
{
    var selectedTypeIds = from t in SelectedWidgetTypes
                          where t.Selected
                          select t.Id;

    var widgets = from d in context.Widgets
                  where selectedTypeIds.Contains(d.WidgetTypeId)                 
                        // other search criteria
                  select d;

    return widgets.ToList();
}
于 2013-11-05T16:01:04.970 回答