1

Albahariの Predicate を使用して、次のような TSQL ステートメントを作成しようとしています。

select * from channel
where channel.VendorID IN (@vendorIDs)
AND channel.FranchiseID IN (@franchiseIDs)

または次のような述語: c => (c.VendorID = x || c.VendorID == x2 ...) && (c.FranchiseID == f || c.FranchiseID == f2 ...)

しかし、私は問題を抱えています。これが私の試みです:

    var vendorPredicate = PredicateBuilder.False<Channel>();
    foreach (Vendor vendor in workOrderSessionData.SelectedVendors)
    {
        int tempId = vendor.VendorID;
        vendorPredicate = vendorPredicate.Or(c => c.VendorID == tempId);
    }

    var franchisePredicate = PredicateBuilder.False<Channel>();
    foreach (Franchise franchise in workOrderSessionData.SelectedFranchises)
    {
        int tempId = franchise.FranchiseID;
        franchisePredicate = franchisePredicate.Or(c => c.FranchiseID == tempId);
        // doesn't work franchisePredicate.Or(vendorPredicate);
    }

Channel.SelectByPredicate(franchisePredicate);

私のテーブルには 60,000 行あるため、データベースに移動してそれらをすべて選択すると、フィルタリングはオプションではありません。チャネルは LinqToSql エンティティです。また、SelectedFranchises または SelectedVendors のいずれかを空にすることはできますが、同時に両方を空にすることはできません。編集:このリストをchannel.Franchise.Nameでも区別する必要があります..ストアドプロシージャを使用する必要がありますか?

これをどのように行いますか?

4

3 に答える 3

2

述語の問題全体を回避するには、「Contains()」ステートメントを使用しないのはなぜですか?

IE

var myResults =
    from c in Channel
    where
        workOrderSessionData.SelectedVendors.Select(sv => 
            sv.VendorID).Contains(c.VendorID)

        && workOrderSessionData.SelectedFranchises.Select(sf => 
            sf.FranchiseID).Contains(c.FranchiseID)
    select c;
Channel.SelectByPredicate(franchisePredicate);

または、述語メソッドを使用するには、例の SQL ステートメントで 2 つの条件が「and」されているため、それらを「or」で結合したくないでしょう。代わりに、where 句を使用して連続して実行します。SelectByPredicate 関数がどのように機能するかはわかりませんが、同じパターンに従って成功する可能性があります。

var myResults = Channel.SelectByPredicate(franchisePredicate);
myResults = myResults.SelectByPredicate(vendorPredicate);

var myResults = Channel.Where(franchisePredicate).Where(vendorPredicate);

コメントのディスカッションから更新

workordersessiondata にこれらの ID が少なくとも 1 つ含まれている場合に、ベンダー ID/フランチャイズ ID のみを照合する場合は、次のロジックを使用します。

List<int> VendorIDs = workOrderSessionData.SelectedVendors.Select(sv => 
    sv.VendorID).ToList();

List<int> FranchiseIDs = workOrderSessionData.SelectedFranchises.Select(sf => 
    sf.FranchiseID).ToList();

var myResults = Channel;

if(VendorIDs.Count > 0)
    myResults = MyResults.Where(c => VendorIDs.Contains(c.VendorID));

if(FranchiseIDs.Count > 0)
    myResults = MyResults.Where(c => FranchiseIDs.Contains(c.FranchiseID));
于 2009-11-19T17:38:26.873 に答える
0

さて、私はこれをやった:

var prope = outerWhere.ToString();
if (prope.Equals("f => True") == false || prope.Equals("f => False") == false)
  query = query.Where(outerWhere);

たぶん、すべてのバージョンの中で最もクリーンです...

于 2010-07-23T09:38:09.977 に答える
0

拡張子を考えると:

public static class PredicateExtensions
{
    public static Predicate<T> Or<T>(this Predicate<T> @this, Predicate<T> or) {
        return value => @this(value) || or(value);
    }

    public static Predicate<T> And<T>(this Predicate<T> @this, Predicate<T> and) {
        return value => @this(value) && and(value);
    }
}

あなたはこれを行うことができます:

    Predicate<Channel> vendorPredicate = c => false;

    foreach (var vendor in workOrderSessionData.SelectedVendors)
    {
        int tempId = vendor.VendorID;       
        vendorPredicate = vendorPredicate.Or(c => c.VendorID == tempId);
    }

    Predicate<Channel> franchisePredicate = c => false;
    foreach (var franchise in workOrderSessionData.SelectedFranchises)
    {
        int tempid = franchise.FranchiseID;
        franchisePredicate = franchisePredicate.Or(c => c.FranchiseID == tempid);
    }

    var channelPredicate = vendorPredicate.And(franchisePredicate);

    var query = Channels.Where (c => channelPredicate(c));
}
于 2012-04-10T08:13:48.653 に答える