Question

Je suis en train d'utiliser le prédicats de Albahari pour créer une déclaration TSQL comme:

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

ou un prédicat comme: c => (c.VendorID = x || c.VendorID == x2 ...) && (c.FranchiseID == f || c.FranchiseID == f2 ...)

mais je vais avoir des problèmes. Voici ma tentative:

    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);

Ma table a 60.000 lignes, afin d'aller à la base de données et en les sélectionnant tous, alors le filtrage est pas une option. Channel est une entité LinqToSql. En outre, soit les SelectedFranchises ou les SelectedVendors peuvent être vides, mais pas les deux à un moment donné. EDIT: Je dois cette liste distincte par le channel.Franchise.Name et .. Peut-être que je devrais utiliser une procédure stockée

?

Comment voulez-vous faire?

Était-ce utile?

La solution

Pour l'autre étape toute la question sous-jacente pourquoi ne pas utiliser la mention « Contient () »?

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);

Vous pouvez également utiliser la méthode sous-jacente, vous ne voudriez pas les joindre à un « ou » parce que les deux conditions sont « et » 'd dans votre exemple instruction SQL. Au lieu de cela, il suffit d'exécuter les consécutivement par une clause where. Je ne sais pas comment votre fonction SelectByPredicate fonctionne, mais vous pouvez réussir suivant le même schéma avec elle:

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

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

Mise à jour de la discussion dans les commentaires

Si ce que vous voulez est de faire correspondre uniquement sur Vendor ID / id de franchise si le workordersessiondata contient au moins un de ces ids, vous utiliseriez la logique suivante:

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));

Autres conseils

Eh bien, je viens de faire ceci:

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

Peut-être tho le plus propre de toutes les versions ...

Compte tenu des extensions:

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);
    }
}

Vous pouvez faire ceci:

    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));
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top