2016-05-26 20 views
5

Mam dwie klasy:C# - Dynamic LINQ z listy stan

public class Customer 
{ 
    public string FirstName { get; set; } 

    public string LastName { get; set; } 

    public List<Product> Product { get; set; } 
} 

public class Product 
{ 
    public string ProductNumber { get; set; } 

    public string ProductColor { get; set; } 
} 

I jedna instancja:

Customer[] c = new Customer[] 
{ 
    new Customer() 
    { 
     FirstName = "FirstName1", 
     LastName = "LastName1", 
     Product = new List<Product> 
     { 
      new Product() 
      { 
       ProductColor = "ProductColor1", 
       ProductNumber = "11" 
      } 
     } 
    }, 
    new Customer() 
    { 
     FirstName = "FirstName2", 
     LastName = "LastName2", 
     Product = new List<Product> 
     { 
      new Product() 
      { 
       ProductColor = "ProductColor2", 
       ProductNumber = "12" 
      } 
     } 
    } 
}; 

używam System.Dynamic.Linq biblioteki do filtrowania moje tablicy:

var filter = c.Where("FirstName == \"FirstName1\"").Select(x => x).ToList();

Tworzę klasę condition i jedną instancję:

public class condition 
{ 
    public string propertyName { get; set; } 

    public string propertyValue { get; set; } 
} 

List<condition> f = new List<condition> 
{ 
    new condition() 
    { 
     propertyName = "FirstName", 
     propertyValue = "FirstName1" 
    }, 
    new condition() 
    { 
     propertyName = "Product.ProductColor", 
     propertyValue = "11" 
    } 
}; 

Chcę utworzyć wiele klauzuli Where z tego List<Condition>

Jak to zrobić?

+2

Czy możesz pokazać kod, w którym aktualnie stosuje się jeden warunek do listy? Powinien być tak prosty jak 'var toFilter = sourceCollection.AsEnumerable(); foreach (warunek var w warunkach) {toFilter = toFilter.Where (warunek); } '. – CodeCaster

+0

Czy Twój łańcuch znaków jest zgodny z Twoimi umowami? –

+0

Nie, wszystkie właściwości nie są ciągiem znaków –

Odpowiedz

1

Z tego, co mogę zebrać, to tylko prosty przypadek wykonania tego na twojej liście? Chyba że czegoś brakuje?

var query = f.Where(x => x.propertyName == "FirstName" && x.propertyValue == "FirstName1"); 
+0

Moja lista warunków pochodzi z pliku konfiguracyjnego –

+0

To może ci pomóc, http://weblogs.asp.net/scottgu/dynamic-linq-part-1-using-the-linq-dynamic-query-library Istnieje do pobrania dynamiczna biblioteka linq z przykładami również tutaj - http://msdn2.microsoft.com/en-us/vcsharp/bb894665.aspx – nik0lias

+0

Cóż, z przykładami dostarczonymi przez link możesz utworzyć ciąg znaków, który będzie reprezentował Twoją instrukcję where na przykład - f. Gdzie ("propertyName = @ 0 and propertyValue = @ 1", "SomeNameHere", "SomeOtherValue"); Możesz więc dynamicznie budować ciąg. – nik0lias

0

Aby rozwiązać problem mam zmodyfikowano trochę swoją klasę stanie jak follwoing:

Warunkiem o potędze klienta zawiera listę warunków produktu:

public class Condition 
    { 
     public string propertyName { get; set; } 
     public string propertyValue { get; set; } 
     public ICollection<Condition> Conditions { get; set; } 
    } 

go utworzyć :

List<Condition> f = new List<Condition> 
    { 
    new Condition() 
    { 
     propertyName = "FirstName", 
     propertyValue = "FirstName1", 
     Conditions = new List<Condition> 
     { 
     new Condition 
     { 
      propertyName = "ProductColor", 
      propertyValue = "11" 
     } 
     } 
    }, 
    }; 

teraz możesz użyć poniższego zapytania do filtrowania klienta i t on produkty o danym stanie/s:

var filteredCustomers = 
       from condition in f 
       from custmer in c 
       from product in custmer.Product 
       let propertyName = condition.propertyName 
       let propertyValue = condition.propertyValue 
       where (nameof(custmer.FirstName) == propertyName && custmer.FirstName == propertyValue) 
        && 
        (condition.Conditions.Any(p => p.propertyName == nameof(product.ProductColor)) 
        && condition.Conditions.Any(p => p.propertyValue == product.ProductNumber)) 
       select custmer; 

      foreach (var filterCustmer in filteredCustomers.Distinct()) 
      { 
       Console.WriteLine(filterCustmer.FirstName); 
      } 
+0

możesz podać nazwę właściwości jako string instated ofof nameof, a problem jest twoją klasą klienta. Ta klasa zawiera listę produktów, co oznacza, że ​​musisz je zmapować za pomocą ideintfiera, ale w twojej klasie nie ma nic, co można by z nim mapować. –