0

I have a db that contains 3 tables

Products Table          Suppliers  Table           Categories Table
Id                      Id                         Id
ProductName             SupplierName               CategoryName
Quantity                .                          .
SupplierId              .                          .
CategoryId
.
.

I am using PredicateBuilder to select Product accoring to the selected product field (Quantity,Productname...) How Can I use PredicateBuilder or any other method to Select the Product according to Its Suppliername or Categoryname

Please I am using VB.NET I saw many C# examples but I can not understand it nor translate it I am thinking of using join in predicateBuilder but I do not how !!!!

To be more clear What I want is to combine multiple field in one search ,Like for example:

Give me a Product where It's Name contains "s" and Quantity <10 and SupplierName is Kimo

Give me a product where i's name contains "g" only

give me the products for categoryName "Machines"

.

.

And this search predicate is changable because Each Products table has many fields ,So the search is dynamic according to selected fields

Waiting for your kind help.

I think Arion answer was correct but It needs some revision AnyWay I came up with this solution ,It is not the most effecient one but It solved my problem.

 Dim SupplierAlso As String = ""
 Dim CategoryAlso As String = ""
 Dim pred = PredicateBuilder.True(Of Products)()
 Select Case Entry
                        Case "Number"
                            Dim Inum = Entry
                            pred = pred.And(Function(m As products) m.ID.Equals(CInt(Inum)))

                        Case "ProductName"

                            Dim IName = Entry
                            pred = pred.And(Function(m As Products) m.ProductName.IndexOf(IName, StringComparison.OrdinalIgnoreCase) >= 0)

. . . Case "Supplier"

                            SupplierAlso = Entry

                        Case "Category"

                            CategoryAlso = Ent 

Next

            Dim f As ProductsDataTable = Products.Product
            Dim tmp As IEnumerable(Of Products) = New ProductsDataTable().AsEnumerable()
            tmp = f.AsEnumerable.Where(pred.Compile)


            Dim qry

             If CategoryAlso = "" And SupplierAlso = "" Then
                q = (From prods In tmp
                      Join Cats In Categories
                      On prods.CategoryId Equals Cats.ID
                      Join Supps In Suppliers
                      On Supps.ID Equals prods.SupplierId
                      Select Supps.SupplierName, Cats.CategoryName, prods.ID _ 
                      , prods.ProductName,   prods.UnitPrice, prods.CategoryId _ 
                      , prods.SupplierId, prods.Location, _
                      prods.Description, prods.SellPrice, prods.CountInStock _ 
                      , prods.ProductionDate, prods.ExpiryDate, _
                      prods.ProductType, prods.ProductSeason).ToList

            ElseIf CategoryAlso <> "" And SupplierAlso <> "" Then

                q = (From prods In tmp
                      Join Cats In Categories
                      On prods.CategoryId Equals Cats.ID
                       Join Supps In Suppliers
                       On Supps.ID Equals prods.SupplierId
                       Where Cats.CategoryName.IndexOf((CategoryAlso)  
                 ,  StringComparison.OrdinalIgnoreCase) >= 0 And _                                Supps.SupplierName.IndexOf((SupplierAlso), _ 
                      StringComparison.OrdinalIgnoreCase) >= 0
                      Select Supps.SupplierName, Cats.CategoryName, prods.ID, _  
                     prods.ProductName, prods.UnitPrice, prods.CategoryId, _ 
                     prods.SupplierId, prods.Location, _
                      prods.Description, prods.SellPrice, prods.CountInStock,  _ 
                      prods.ProductionDate, prods.ExpiryDate, _
                      prods.ProductType, prods.ProductSeason).ToList

            ElseIf SupplierAlso <> "" And CategoryAlso = "" Then

                q = (From prods In tmp
                        Join Cats In Categories
                        On Cats.ID Equals prods.CategoryId
                        Join Supps In Suppliers
                        On prods.SupplierId Equals Supps.ID Where _ 
                         Supps.SupplierName.IndexOf((SupplierAlso),  _ 
                         StringComparison.OrdinalIgnoreCase) >= 0
                        Select Cats.CategoryName, Supps.SupplierName, prods.ID,  _ 
                        prods.ProductName, prods.UnitPrice, prods.CategoryId, _ 
                        prods.SupplierId, prods.Location, _
                        prods.Description, prods.SellPrice, prods.CountInStock, _  
                        prods.ProductionDate, prods.ExpiryDate, _
                        prods.ProductType, prods.ProductSeason).ToList

            ElseIf CategoryAlso <> "" And SupplierAlso = "" Then

                q = (From prods In tmp
                        Join Cats In Categories
                        On prods.CategoryId Equals Cats.ID Where Cats.CategoryName.IndexOf _ 
                        ((CategoryAlso), StringComparison.OrdinalIgnoreCase) >= 0
                        Join Supps In Suppliers On Supps.ID Equals prods.SupplierId
                        Select Supps.SupplierName, Cats.CategoryName, prods.ID, _ 
                        prods.ProductName, prods.UnitPrice, prods.CategoryId, _ 
                        prods.SupplierId, prods.Location, _
                        prods.Description, prods.SellPrice, prods.CountInStock, _ 
                        prods.ProductionDate, prods.ExpiryDate, _
                        prods.ProductType, prods.ProductSeason).ToList

            End If

For Each it In q With it

                    DataGridView2.Rows.Add _ 
                   ({.ID, .ProductName, .UnitPrice, .categoryname, .suppliername, .Location, _
                                            .Description, .SellPrice, .CountInStock, _                                                .ProductionDate, .ExpiryDate, _
                                            .ProductType, .ProductSeason})

                End With

            Next

So what do you think ,Is there a better way? Ofcourse yes?Silly question ,But Where?

ali haider
  • 333
  • 3
  • 13

1 Answers1

0

So i would do something like this then. I have simplify the where statements but I think you will get my point:

dim checkCategoryName as boolean=true
dim checkSupplier as boolean=true
dim checkQuantity as boolean=true
dim query= db.Products.Select (function(p) p)
if checkCategoryName then
    query=query _ 
            .Where (function(p) db.Categories.Where (function(c) c.CategoryName="??" ) _ 
            .Select (function(c) c.Id) _ 
            .Contains(p.CategoryId))
end if
if checkSupplier then
    query=query _ 
            .Where (function(q) db.Suppliers.Where (function(s) s.SupplierName="??") _ 
            .Select (function(s) s.Id) _ 
            .Contains(q.SupplierId))
end if
if checkQuantity then
    query=query.Where (function(q) q.Quantity<10)
end if
dim result=query.ToList()

Where db is the linq data context.

Arion
  • 31,011
  • 10
  • 70
  • 88
  • Thank you but not this is what I am looking for , Kimo ,"s" and <10 is just an imaginary example I want to make a dynamic search with changing fields selected by the user ,May be by using PredicateBuilder and join method ,I am not sure how? – ali haider Feb 06 '12 at 10:51
  • It liked your solution but I do not know Why I can not detect CategoryName field even in late bound way as .Item("CategoryName").Tostring – ali haider Feb 06 '12 at 14:21