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

ウィジェット タイプ 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 に答える
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 に答える