Reputation: 331
I wanted to make the table used for the expression be set dynamically
Here is my code
PayoutEntities payoutdb = new PayoutEntities();
public String AutoID(String idFormat, String tablename)
{
string curdate = DateTime.Today.ToShortDateString().Replace("/", "");
if (tablename == "users"){
var count = payoutdb.users.Count(x => x.userid.Substring(0,10) == idFormat + curdate);
}else if (tablename == "transactions"){
var count = payoutdb.transactions.Count(x => x.transid.Substring(0,10) == idFormat + curdate);
}
count++;
string ID = idFormat + curdate + count.ToString("0000");
return ID;
}
Currently I have an autoid function for all tables in my database so now I'm thinking of a way to make a shorter code rather than placing my code in an if statement. Is there anyway to set the table used in linq lambda expression dynamically?
Upvotes: 0
Views: 135
Reputation: 30464
My advice would be not to use a string to identify the table to use, but to make a generic function where the type of the table is the parameter of the generic function.
Assuming payoutDb is your DbContext, you can use DbContext.Set to access the proper table:
public string AutoId<TableType>(string idFormat)
{
string curdate = DateTime.Today.ToShortDateString().Replace("/", "");
var count = payoutdb.Set<TableType>()
.Count(x => x.userid.Substring(0,10) == idFormat + curdate);
count++;
string ID = idFormat + curdate + count.ToString("0000");
return ID;
}
note: every x
in the Count is of type TableType
, so it is a user
, or a transaction
.
Usage: Using your proposed code, somewhere in your code, you would call the function like this:
string someIdFormat = ...
string autoId = AutoId(someIdFormat, "users");
Using my proposed function this would become:
string autoId = AutoId<User>(someIdFormat);
One of the problems you'll have to overcome, is that you have to tell your AutoId function that users
and transactions
and all other tables you wanted to use in AutoId
have a property AutoId
.
A method you could use, would be to define an interface:
interface IAutoId
{
string AutoId {get;}
}
class User : IAutoId
{
public string AutoId {set; set;}
...
}
class Transation: IAutoId
{
public string AutoId {set; set;}
...
}
public string AutoId<TableType>(string idFormat) where TableType: IAutoId
{
...
If you don't want to do this for the tables that you want to use, consider telling the AutoId function which property it should use:
public string AutoId<TableType>(string idFormat, Func<TableType, string> propertySelector)
{
...
var count = payoutdb.Set<TableType>()
.Count(x => propertySelector(x).Substring(0,10) == idFormat + curdate);
...
}
You want the part propertySelector(x)
to call x.UserId
, so you would call the function like this:
string autoId = AutoId<User>(someIdFormat, user => user.UserId);
The nice thing about this method is that you can use your function also for other properties:
string autoId = AutoId<User>(someIdFormat, user => user.UserName);
Upvotes: 2
Reputation: 145
The table is a property of PayoutEntities, so you could get that property by name using GetProperty(). Once you have the property, you should be able to use linq with it.
Upvotes: 0