Generic function with different object parameters












-1















I want to implement server side filtering for two data tables having different IQueryable list



public IQueryable<ClassA> search(IQueryable<ClassA> query,string name,string number)
{
if (name!= null )
query = query.Where( a =>a.name.Contains(name) );
if (number!= null )
query = query.Where( a =>a.number.ToString().Contains(numbr) );
return query;
}


and



public IQueryable<ClassB> search(IQueryable<ClassB> query,string address, string email)
{
if (address!= null )
query = query.Where( a =>a.name.Contains(address) );
if (email!= null )
query = query.Where( a =>a.email.Contains(email) );
return query;
}


Since the implementation is same but ClassA and ClassB has different attributes involving different checks to search the value.



How to make a single generic function where I can perform searching with both of these classes?










share|improve this question

























  • I doubt generics are the way to go. make a abstract class with a abstraact "query" function. The ClassA and ClassB inherit from it. accept any AbstractClass variant.

    – Christopher
    Nov 17 '18 at 19:31











  • that still requires two different functions

    – rashidali
    Nov 17 '18 at 19:40











  • Could you describe what that is supposed to happen in this function? It returns void?

    – Ruud Kobes
    Nov 17 '18 at 19:42













  • @RuudKobes check the code

    – rashidali
    Nov 17 '18 at 19:55






  • 1





    Why do you need to have a single function for this? It seems like you're doing two different things. The only thing these methods have in common is that they contain where clauses. Making a single method for this will probably only make your code harder to understand.

    – Jesse de Wit
    Nov 17 '18 at 20:54
















-1















I want to implement server side filtering for two data tables having different IQueryable list



public IQueryable<ClassA> search(IQueryable<ClassA> query,string name,string number)
{
if (name!= null )
query = query.Where( a =>a.name.Contains(name) );
if (number!= null )
query = query.Where( a =>a.number.ToString().Contains(numbr) );
return query;
}


and



public IQueryable<ClassB> search(IQueryable<ClassB> query,string address, string email)
{
if (address!= null )
query = query.Where( a =>a.name.Contains(address) );
if (email!= null )
query = query.Where( a =>a.email.Contains(email) );
return query;
}


Since the implementation is same but ClassA and ClassB has different attributes involving different checks to search the value.



How to make a single generic function where I can perform searching with both of these classes?










share|improve this question

























  • I doubt generics are the way to go. make a abstract class with a abstraact "query" function. The ClassA and ClassB inherit from it. accept any AbstractClass variant.

    – Christopher
    Nov 17 '18 at 19:31











  • that still requires two different functions

    – rashidali
    Nov 17 '18 at 19:40











  • Could you describe what that is supposed to happen in this function? It returns void?

    – Ruud Kobes
    Nov 17 '18 at 19:42













  • @RuudKobes check the code

    – rashidali
    Nov 17 '18 at 19:55






  • 1





    Why do you need to have a single function for this? It seems like you're doing two different things. The only thing these methods have in common is that they contain where clauses. Making a single method for this will probably only make your code harder to understand.

    – Jesse de Wit
    Nov 17 '18 at 20:54














-1












-1








-1








I want to implement server side filtering for two data tables having different IQueryable list



public IQueryable<ClassA> search(IQueryable<ClassA> query,string name,string number)
{
if (name!= null )
query = query.Where( a =>a.name.Contains(name) );
if (number!= null )
query = query.Where( a =>a.number.ToString().Contains(numbr) );
return query;
}


and



public IQueryable<ClassB> search(IQueryable<ClassB> query,string address, string email)
{
if (address!= null )
query = query.Where( a =>a.name.Contains(address) );
if (email!= null )
query = query.Where( a =>a.email.Contains(email) );
return query;
}


Since the implementation is same but ClassA and ClassB has different attributes involving different checks to search the value.



How to make a single generic function where I can perform searching with both of these classes?










share|improve this question
















I want to implement server side filtering for two data tables having different IQueryable list



public IQueryable<ClassA> search(IQueryable<ClassA> query,string name,string number)
{
if (name!= null )
query = query.Where( a =>a.name.Contains(name) );
if (number!= null )
query = query.Where( a =>a.number.ToString().Contains(numbr) );
return query;
}


and



public IQueryable<ClassB> search(IQueryable<ClassB> query,string address, string email)
{
if (address!= null )
query = query.Where( a =>a.name.Contains(address) );
if (email!= null )
query = query.Where( a =>a.email.Contains(email) );
return query;
}


Since the implementation is same but ClassA and ClassB has different attributes involving different checks to search the value.



How to make a single generic function where I can perform searching with both of these classes?







c# asp.net datatables






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 17 '18 at 19:54







rashidali

















asked Nov 17 '18 at 19:09









rashidalirashidali

3518




3518













  • I doubt generics are the way to go. make a abstract class with a abstraact "query" function. The ClassA and ClassB inherit from it. accept any AbstractClass variant.

    – Christopher
    Nov 17 '18 at 19:31











  • that still requires two different functions

    – rashidali
    Nov 17 '18 at 19:40











  • Could you describe what that is supposed to happen in this function? It returns void?

    – Ruud Kobes
    Nov 17 '18 at 19:42













  • @RuudKobes check the code

    – rashidali
    Nov 17 '18 at 19:55






  • 1





    Why do you need to have a single function for this? It seems like you're doing two different things. The only thing these methods have in common is that they contain where clauses. Making a single method for this will probably only make your code harder to understand.

    – Jesse de Wit
    Nov 17 '18 at 20:54



















  • I doubt generics are the way to go. make a abstract class with a abstraact "query" function. The ClassA and ClassB inherit from it. accept any AbstractClass variant.

    – Christopher
    Nov 17 '18 at 19:31











  • that still requires two different functions

    – rashidali
    Nov 17 '18 at 19:40











  • Could you describe what that is supposed to happen in this function? It returns void?

    – Ruud Kobes
    Nov 17 '18 at 19:42













  • @RuudKobes check the code

    – rashidali
    Nov 17 '18 at 19:55






  • 1





    Why do you need to have a single function for this? It seems like you're doing two different things. The only thing these methods have in common is that they contain where clauses. Making a single method for this will probably only make your code harder to understand.

    – Jesse de Wit
    Nov 17 '18 at 20:54

















I doubt generics are the way to go. make a abstract class with a abstraact "query" function. The ClassA and ClassB inherit from it. accept any AbstractClass variant.

– Christopher
Nov 17 '18 at 19:31





I doubt generics are the way to go. make a abstract class with a abstraact "query" function. The ClassA and ClassB inherit from it. accept any AbstractClass variant.

– Christopher
Nov 17 '18 at 19:31













that still requires two different functions

– rashidali
Nov 17 '18 at 19:40





that still requires two different functions

– rashidali
Nov 17 '18 at 19:40













Could you describe what that is supposed to happen in this function? It returns void?

– Ruud Kobes
Nov 17 '18 at 19:42







Could you describe what that is supposed to happen in this function? It returns void?

– Ruud Kobes
Nov 17 '18 at 19:42















@RuudKobes check the code

– rashidali
Nov 17 '18 at 19:55





@RuudKobes check the code

– rashidali
Nov 17 '18 at 19:55




1




1





Why do you need to have a single function for this? It seems like you're doing two different things. The only thing these methods have in common is that they contain where clauses. Making a single method for this will probably only make your code harder to understand.

– Jesse de Wit
Nov 17 '18 at 20:54





Why do you need to have a single function for this? It seems like you're doing two different things. The only thing these methods have in common is that they contain where clauses. Making a single method for this will probably only make your code harder to understand.

– Jesse de Wit
Nov 17 '18 at 20:54












3 Answers
3






active

oldest

votes


















0














Possible solution, using object reflection. Parameter has two strings in pair. First is the name of property, second is the value of it.



 public IQueryable<T> search(IQueryable<T> query, params Tuple<string, string> parameters)
{
Type type = typeof(T);
PropertyInfo properties = type.GetProperties();
foreach(var parameter in parameters)
{
PropertyInfo pi = properties.Where(a => a.Name == parameter.Item1).FirstOrDefault();
if (pi != null)
{
query = query.Where(a => pi.GetValue(a).ToString().Contains(parameter.Item2));
}
}

return query;
}





share|improve this answer


























  • meets the requirements

    – rashidali
    Nov 18 '18 at 6:44



















0














You can make both clases of the same interface IPropertyWalker for example. It should have thestring indexer.



public string this[string key]
{
switch(key)
{
case "Name"
return Name;
//list all you need for your class
}
}



And then pass property names to compare data.






share|improve this answer































    -1














    Improving on @wannadreams response, you can lookup property information only if member type of the target is a property. Here is a full example.



            class ClassA
    {
    // Will work
    public string Name { get; set; }
    // Will not work
    public string Name;
    }

    public static async Task Main(string args)
    {
    IQueryable<ClassA> query = ...
    search(query, Tuple.Create(nameof(ClassA.Name), "myName"));
    }

    public static IQueryable<T> search<T>(
    IQueryable<T> query,
    params Tuple<string, string> parameters)
    where T : class
    {
    foreach(var criteria in parameters) {
    var property = typeof(T).GetProperty(criteria.Item1);
    if (property == null) continue;
    // you also need to verify the property was retrievable from the instance.
    query = query.Where(item => property.GetValue(item) != null)
    .Where(item => property.GetValue(item).ToString().Contains(criteria.Item2));
    }

    return query;
    }





    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53354589%2fgeneric-function-with-different-object-parameters%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      0














      Possible solution, using object reflection. Parameter has two strings in pair. First is the name of property, second is the value of it.



       public IQueryable<T> search(IQueryable<T> query, params Tuple<string, string> parameters)
      {
      Type type = typeof(T);
      PropertyInfo properties = type.GetProperties();
      foreach(var parameter in parameters)
      {
      PropertyInfo pi = properties.Where(a => a.Name == parameter.Item1).FirstOrDefault();
      if (pi != null)
      {
      query = query.Where(a => pi.GetValue(a).ToString().Contains(parameter.Item2));
      }
      }

      return query;
      }





      share|improve this answer


























      • meets the requirements

        – rashidali
        Nov 18 '18 at 6:44
















      0














      Possible solution, using object reflection. Parameter has two strings in pair. First is the name of property, second is the value of it.



       public IQueryable<T> search(IQueryable<T> query, params Tuple<string, string> parameters)
      {
      Type type = typeof(T);
      PropertyInfo properties = type.GetProperties();
      foreach(var parameter in parameters)
      {
      PropertyInfo pi = properties.Where(a => a.Name == parameter.Item1).FirstOrDefault();
      if (pi != null)
      {
      query = query.Where(a => pi.GetValue(a).ToString().Contains(parameter.Item2));
      }
      }

      return query;
      }





      share|improve this answer


























      • meets the requirements

        – rashidali
        Nov 18 '18 at 6:44














      0












      0








      0







      Possible solution, using object reflection. Parameter has two strings in pair. First is the name of property, second is the value of it.



       public IQueryable<T> search(IQueryable<T> query, params Tuple<string, string> parameters)
      {
      Type type = typeof(T);
      PropertyInfo properties = type.GetProperties();
      foreach(var parameter in parameters)
      {
      PropertyInfo pi = properties.Where(a => a.Name == parameter.Item1).FirstOrDefault();
      if (pi != null)
      {
      query = query.Where(a => pi.GetValue(a).ToString().Contains(parameter.Item2));
      }
      }

      return query;
      }





      share|improve this answer















      Possible solution, using object reflection. Parameter has two strings in pair. First is the name of property, second is the value of it.



       public IQueryable<T> search(IQueryable<T> query, params Tuple<string, string> parameters)
      {
      Type type = typeof(T);
      PropertyInfo properties = type.GetProperties();
      foreach(var parameter in parameters)
      {
      PropertyInfo pi = properties.Where(a => a.Name == parameter.Item1).FirstOrDefault();
      if (pi != null)
      {
      query = query.Where(a => pi.GetValue(a).ToString().Contains(parameter.Item2));
      }
      }

      return query;
      }






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 17 '18 at 20:21

























      answered Nov 17 '18 at 20:14









      wannadreamwannadream

      1,4351811




      1,4351811













      • meets the requirements

        – rashidali
        Nov 18 '18 at 6:44



















      • meets the requirements

        – rashidali
        Nov 18 '18 at 6:44

















      meets the requirements

      – rashidali
      Nov 18 '18 at 6:44





      meets the requirements

      – rashidali
      Nov 18 '18 at 6:44













      0














      You can make both clases of the same interface IPropertyWalker for example. It should have thestring indexer.



      public string this[string key]
      {
      switch(key)
      {
      case "Name"
      return Name;
      //list all you need for your class
      }
      }



      And then pass property names to compare data.






      share|improve this answer




























        0














        You can make both clases of the same interface IPropertyWalker for example. It should have thestring indexer.



        public string this[string key]
        {
        switch(key)
        {
        case "Name"
        return Name;
        //list all you need for your class
        }
        }



        And then pass property names to compare data.






        share|improve this answer


























          0












          0








          0







          You can make both clases of the same interface IPropertyWalker for example. It should have thestring indexer.



          public string this[string key]
          {
          switch(key)
          {
          case "Name"
          return Name;
          //list all you need for your class
          }
          }



          And then pass property names to compare data.






          share|improve this answer













          You can make both clases of the same interface IPropertyWalker for example. It should have thestring indexer.



          public string this[string key]
          {
          switch(key)
          {
          case "Name"
          return Name;
          //list all you need for your class
          }
          }



          And then pass property names to compare data.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 17 '18 at 20:36









          Влад СтовманенкоВлад Стовманенко

          74




          74























              -1














              Improving on @wannadreams response, you can lookup property information only if member type of the target is a property. Here is a full example.



                      class ClassA
              {
              // Will work
              public string Name { get; set; }
              // Will not work
              public string Name;
              }

              public static async Task Main(string args)
              {
              IQueryable<ClassA> query = ...
              search(query, Tuple.Create(nameof(ClassA.Name), "myName"));
              }

              public static IQueryable<T> search<T>(
              IQueryable<T> query,
              params Tuple<string, string> parameters)
              where T : class
              {
              foreach(var criteria in parameters) {
              var property = typeof(T).GetProperty(criteria.Item1);
              if (property == null) continue;
              // you also need to verify the property was retrievable from the instance.
              query = query.Where(item => property.GetValue(item) != null)
              .Where(item => property.GetValue(item).ToString().Contains(criteria.Item2));
              }

              return query;
              }





              share|improve this answer




























                -1














                Improving on @wannadreams response, you can lookup property information only if member type of the target is a property. Here is a full example.



                        class ClassA
                {
                // Will work
                public string Name { get; set; }
                // Will not work
                public string Name;
                }

                public static async Task Main(string args)
                {
                IQueryable<ClassA> query = ...
                search(query, Tuple.Create(nameof(ClassA.Name), "myName"));
                }

                public static IQueryable<T> search<T>(
                IQueryable<T> query,
                params Tuple<string, string> parameters)
                where T : class
                {
                foreach(var criteria in parameters) {
                var property = typeof(T).GetProperty(criteria.Item1);
                if (property == null) continue;
                // you also need to verify the property was retrievable from the instance.
                query = query.Where(item => property.GetValue(item) != null)
                .Where(item => property.GetValue(item).ToString().Contains(criteria.Item2));
                }

                return query;
                }





                share|improve this answer


























                  -1












                  -1








                  -1







                  Improving on @wannadreams response, you can lookup property information only if member type of the target is a property. Here is a full example.



                          class ClassA
                  {
                  // Will work
                  public string Name { get; set; }
                  // Will not work
                  public string Name;
                  }

                  public static async Task Main(string args)
                  {
                  IQueryable<ClassA> query = ...
                  search(query, Tuple.Create(nameof(ClassA.Name), "myName"));
                  }

                  public static IQueryable<T> search<T>(
                  IQueryable<T> query,
                  params Tuple<string, string> parameters)
                  where T : class
                  {
                  foreach(var criteria in parameters) {
                  var property = typeof(T).GetProperty(criteria.Item1);
                  if (property == null) continue;
                  // you also need to verify the property was retrievable from the instance.
                  query = query.Where(item => property.GetValue(item) != null)
                  .Where(item => property.GetValue(item).ToString().Contains(criteria.Item2));
                  }

                  return query;
                  }





                  share|improve this answer













                  Improving on @wannadreams response, you can lookup property information only if member type of the target is a property. Here is a full example.



                          class ClassA
                  {
                  // Will work
                  public string Name { get; set; }
                  // Will not work
                  public string Name;
                  }

                  public static async Task Main(string args)
                  {
                  IQueryable<ClassA> query = ...
                  search(query, Tuple.Create(nameof(ClassA.Name), "myName"));
                  }

                  public static IQueryable<T> search<T>(
                  IQueryable<T> query,
                  params Tuple<string, string> parameters)
                  where T : class
                  {
                  foreach(var criteria in parameters) {
                  var property = typeof(T).GetProperty(criteria.Item1);
                  if (property == null) continue;
                  // you also need to verify the property was retrievable from the instance.
                  query = query.Where(item => property.GetValue(item) != null)
                  .Where(item => property.GetValue(item).ToString().Contains(criteria.Item2));
                  }

                  return query;
                  }






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 17 '18 at 20:35









                  AlchemyAlchemy

                  4253




                  4253






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53354589%2fgeneric-function-with-different-object-parameters%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      這個網誌中的熱門文章

                      Xamarin.form Move up view when keyboard appear

                      Post-Redirect-Get with Spring WebFlux and Thymeleaf

                      Anylogic : not able to use stopDelay()