Reputation: 93
My app works with 5 tables right now, maybe more in the future, and I would like to minimize code duplication. One example below is for Swd0004 and I also have the same code for Swd0013, and other duplicated functions for each table. The user chooses what table to work with from a drop down box. I'd like to take this drop down box selection and somehow pass that to the functions.
private void SWD_0004_Lookup()
{
using (var ctx = new EFContext())
{
var query = ctx.Swd0004;
var readList = query.ToList();
Debug.WriteLine("QUERY COUNT: " + readList.Count);
// create datatable from query results so I can populate datagridview
var dt = LINQResultToDataTable(query);
dgvQueryResults.DataSource = dt;
GetColumnHeaders(dt);
DataDT = dt; // copy local dt so we can use DataDT for getting record data
}
}
This is a database first app. Swd0004 is a table in a database and therefore a DbSet in my EFContext class.
My Swd0004
class:
namespace SWDDB.Models
{
public partial class Swd0004
{
public int Id { get; set; }
public string PartNumber { get; set; }
...
Then do I need to add a generic to it to implement @abdusco answer? Maybe I'm not familiar enough with generics.
public partial class Swd0004<TEntity> : ??? where TEntity : class
Here's another example:
private List<Swd0004> ConvertDT(DataTable dt)
{
var importList = new List<Swd0004>();
// convert DataRow object to SWD object, otherwise BulkInsert will fail
foreach (DataRow row in dt.Rows)
{
var obj = CreateItemFromRow<Swd0004>(row);
// BulkInsert needs a list
importList.Add(obj);
}
return importList;
}
As you can see, I have to explicitly state Swd0004 three times. So I would have to duplicate this function for each table, 5 times.
UPDATE
I'm trying to implement what @bolkay suggested. I created this class:
using SWDDB.Models;
using System.Diagnostics;
using System.Linq;
namespace SWDDB
{
public abstract class BaseLookup<TEntity> where TEntity : class
{
public virtual void PerformLookup()
{
using (var ctx = new EFContext())
{
var query = ctx.Set<TEntity>();
Debug.WriteLine("QUERY COUNT: " + query.ToList().Count);
}
}
}
public class SWD0004Lookup : BaseLookup<Swd0004>
{
}
}
It feels like I'm close but I can't figure out how to call PerformLookup from my mainline code.
Upvotes: 0
Views: 248
Reputation: 11081
You can get a DbSet
using DbContext.Set<TEntity>()
instead of using properties in your EfContext
class:
private void SWD_Lookup<TEntity>() // <-- turn it into a generic method
{
using (var ctx = new EFContext())
{
var query = ctx.Set<TEntity>(); // <-- get dbset by passing the type
// ...
}
}
then you can call it like this:
SWD_Lookup<Swd0004>();
SWD_Lookup<Swd0013>();
Upvotes: 0
Reputation: 1909
I don't fully understand the logic behind users selecting a table to work with.
You can do something like this as a starting point to remove duplication of methods.
Create a base class with the logic.
public abstract class BaseLookUp<TEntity> where TEntity : class
{
public virtual void PerformLookup()
{
using (var ctx = new EFContext())
{
var query = ctx.Set<TEntity>();
//etc...
}
}
}
public class SWD004Lookup : BaseLookUp<SWD004004>
{
}
Totally depending on your needs, you could just make it a static method etc.
Upvotes: 1