简体   繁体   中英

How to dynamically query the database using LINQ and a variable?

I have a database table that has 100 columns, labeled D1,D2,D3 and so on out to 100.

In my method (ASP.NET MVC) I need to check if these columns are null, before displaying them in a table in my view. I really don't want to have to do this :

if(db.Datatable.Select(x=>x.D1).FirstOrDefault() != null)
{
  //do code
}
if(db.Datatable.Select(x=>x.D2).FirstOrDefault() != null)
{
  //do code
}
if(db.Datatable.Select(x=>x.D3).FirstOrDefault() != null)
{
  //do code
}

That would be 100 if statements and just look horrible. So I started this code here:

  for(int i = 1; i < 100; i++)
  {
       var dbField = "D" + i;  //D1,D2,D3....

       var currField = db.Datatable.Select(x => x.dbField).FirstOrDefault();


       //here i would add the value (0 for null, 1 for data) to an array, which i would handle in the view
  }

Except LINQ/C# does not like this. It obviously throws an error on dbField in the Select statement. You can't just set .Select(x=x.variable). I have read on creating your own lambda expression tree and building a custom dynamic query, any thoughts on how to do this? How can I custom create the field name for the Select statement? Thank you.

There is no reason to repeatedly take the first element from the same unchanging collection. Simple take the first element from the collection, and then work with that retrieved object:

var element = db.Datatable.FirstOrDefault();

This already dramatically simplifies your code and improves performance (because you don't need to iterate over the collection for every property):

if(element.D1 != null)
{
    //do code
}

// and so on...

It is unclear exactly why you need to ascertain that each field contains a not-null value. You never posted any code that shows how you intend to use these values.

//here i would add the value (0 for null, 1 for data) to an array, which i would handle in the view

Generally, it's better to simply ensure that your view can handle nulls , as this means you don't need to worry about your code executing when a certain value is null.

If that is not possible, then it's still easier to simply convert null values into a default not-null value. This means you still don't have to worry about nulls (after you've converted them) since you won't have any null values anymore.

A simple way to do this is by using the null coalescing operator, eg

var firstName = element.D1 ?? String.Empty;

This ensures that null values get replaced by a default value (which you can specify, I just chose an empty string here but you can pick whatever you want).

Also note that you don't even need to do this for non-nullable values such as int , as these will default to 0 automatically.

//here i would add the value to an array

Why use an array instead of an object? It's unclear why you are deadset on manually handling every property (and its value) instead of passing the object by itself, which is far and away the better OOP way of passing data.

It's contradictory to at the same time want to handle all data manually and also not want to have to handle all that data.

I think if you explain more precisely what do you want to do in your view we will be able to help you better.

When i see you code, i deduce that your table in your view will display just one record with his appropriate properties/columns. If you want to do that, its ok.

On the other hand, iterate over a table according to the number of columns is a bad idea because your are coupling two abstraction levels. What i mean is that your MVC Method should NOT have knowledge of the number of columns and this is what your are doing with "for(int i = 1; i < 100; i++)". Indeed, what happen if there is a table schema update and the number of columns changes ? The same for the name of the columns ? Your code will be break !

I think you are taking the problem from the wrong side to me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM