Динамикалық linq-ке sql-ге дейінгі балалар кестелерін сұрау?

Менде жазуға болатын өте күрделі сұрау бар. Мен мүмкіндігінше Linq-тен Sql-ді пайдалана отырып мұны істеуге үміттемін. Дерекқор мына сияқты:

Клиенттер (бірінші, соңғы, идентификатор, жынысы)
Тапсырыстар (күні, саны, салмағы, ItemName, бағасы)
Мекен-жайы (Қала, мемлекет, Зип)

The query would be to let a user search by any of these fields, and in the case of the number fields, to search <, =, or > as they desire.

Осындай нәрсе мына нәрселерді орындауды талап ететін іріктеме сұрау болады:

Query 1: Select customers where first name = 'John' and have at least one order with (Weight > 40 OR Quantity > 10 OR Price > 5) and zipcode = 12345.

Query 2: Select customers where first name = 'John' and have at least one order with Weight < 20 and ItemName = 'widget' and Quantity = 10) and zipcode = 12345.

I can get the basic part of searching for customers, but I am stuck on searching the Order table where the user can specify <>= in an OR manner.



query = Context.Customers.AsQueryable();
if (searchingFirstName) query = query.Where(cust => cust.First == firstName);
if (searchingLastName) query = query.Where(cust => cust.Last == lastName);
if (searchingZip) query = query.Where(cust => cust.Address.Zip == zip);

// using dynamic Linq
if (searchingGender) query = query.Where("Gender == @0", gender);

// how do I search the Orders?  The dynamic linq functions appear
// to only work on the top level table

0

1 жауаптар

PredicateBuilder бағдарламасын LinqKit арқылы пайдалана аласыз. Ол ламбдаларды белгілеу үшін жаңа кеңейтілім әдістерін қосады:

var predicate = PredicateBuilder.True();

if (searchingFirstName)
{
    predicate = predicate.And(cust => cust.First == firstName);
}

if (searchingOrders)
{
   //Some code to unify the .And() and .Or() cases
    Expression> subpredicate;
    Func>, Expression>, Expression>> joiner;
    if (orderMethodAny)
    {
        subpredicate = PredicateBuilder.True();
        joiner = PredicateBuilder.And;
    }
    else
    {
        subpredicate = PredicateBuilder.False();
        joiner = PredicateBuilder.Or;
    }

    if (searchingOrderDate)
    {
       //...
    }

    if (searchingOrderWeight)
    {
        switch (orderOp)
        {
            case Op.Less:
                subpredicate = joiner(subpredicate, ord => ord.Weight < orderWeight);
                break;
            case Op.LessEqual:
                subpredicate = joiner(subpredicate, ord => ord.Weight <= orderWeight);
                break;
            case Op.Equal:
                subpredicate = joiner(subpredicate, ord => ord.Weight == orderWeight);
                break;
            case Op.GreaterEqual:
                subpredicate = joiner(subpredicate, ord => ord.Weight >= orderWeight);
                break;
            case Op.Greater:
                subpredicate = joiner(subpredicate, ord => ord.Weight > orderWeight);
                break;
            case Op.NotEqual:
                subpredicate = joiner(subpredicate, ord => ord.Weight != orderWeight);
                break;
        }
    }

    if (searchingOrderQuantity)
    {
      //... 
    }

    if (searchingOrderItemName)
    {
       //...
    }

    if (searchingOrderPrice)
    {
       //...
    }

    predicate = predicate.And(cust => cust.Orders.Any(subpredicate));
}

if (searchingZipCode)
{
    predicate = predicate.And(cust => cust.ZipCode == zipCode);
}

var query = Context.Customers.Where(predicate);

Егер Сіз Entity Framework пайдалансаңыз, сұрау үшін, .Expandable() немесе .expandable() .

1
қосылды
.Compile() пішінді делегатқа түрлендіреді. Жүйе дерекқордың орнына клиенттегі сүзгіні жасайды.
қосылды автор Markus Jarderot, көзі
Көп рақмет. Үлкен жауап. Мен субпедикатта Compile() шақыруға тура келді. predicate = predicate.And (cust => cust.Orders.Any (subpredicate.Compile ()); Өкінішке орай, менің түсінуімше, менің сұрағым дұрыс емес.
қосылды автор David, көзі
Нақты сұранысты пайдалану үшін оны қайта жазғаннан кейін, мен Expand (), AsExpandable() немесе Compile() қажет емес. Бірақ оның тамаша жұмыс істейді.
қосылды автор David, көзі