patterncsharpMinor
Extension method to do Linq Lookups
Viewed 0 times
linqlookupsmethodextension
Problem
Does this extension method contain unnecessary work? - Thanks for reviewing
Scenario - A series of tables are Key-Value pairs (Int "Id" / nvarChar "Title"). This extension method "dots-off" any integer ("Id") and provide the corresponding string value ("Title") given a target "type"
Used in aspx-code-behind. An extension method was chosen for readable one-liners. There are many panels with similar controls to be set conditionally.
Scenario - A series of tables are Key-Value pairs (Int "Id" / nvarChar "Title"). This extension method "dots-off" any integer ("Id") and provide the corresponding string value ("Title") given a target "type"
Used in aspx-code-behind. An extension method was chosen for readable one-liners. There are many panels with similar controls to be set conditionally.
// aspx.cs
txtParentGender.Text=parent.GenderId.RhGet(typeof(Gender)); //male, female
txtParentEthnicity.Text=parent.EthnicityId.RhGet(typeof(Ethnicity)); //Caucasian, etc.
txtParentMaritalStatus.Text=parent.MaritalStatusId.RhGet(typeof(MaritalStatus)); // married, divorced etc.
txtChildGender.Text=child.GenderId.RhGet(typeof(Gender));
txtChildEthnicity.Text=child.EthnicityId.RhGet(typeof(Ethnicity));
txtChildRelation.Text=child.RelationId.RhGet(typeof(Relation)); //son, daughter etc.
// class.cs
using System.Linq.Dynamic; // nuget package
public static string RhGet(this int id, Type type )
{
string returnValue = string.Empty;
// set up data context
using (MyDataContext dc = new MyDataContext())
{
// get table corresponding to this type
var table = dc.GetTable(type);
// match and select record using "id"
var matchingRecord = ((IQueryable)table).Where(string.Format("Id.Equals({0})", id))
.Select("new(Title)").Cast().FirstOrDefault();
// do a lot of contorting to finally get the string value
returnValue = matchingRecord.GetType().GetProperty("Title").GetValue(matchingRecord,null).ToString();
}
return returnValue;
}Solution
I would not write this extension method for
Also, as a rule of thumb, if you're using strings that contain structural metadata about your objects, it's generally a sign you might want to rethink your approach.
Instead, I would find a way to apply an interface to your tables that have this structure, so you could then make an extension method for that interface, or a method that takes in an instance that implements that interface. That way you don't have to rely on strings at all.
If you are really committed to having a method that finds a value based on an int and type inputs, I would change the method to be a static, non-extension method, passing in the int and type.
I also came up with this alternative solution. Although it doesn't behave the same as your original example, you might benefit by using a type parameter so you get a strongly-typed entity returned by your method, which your code will know has a "Title" property:
I also noticed you are instantiating a datacontext in this method--you might want to either pass it in or make this an extension method on your datacontext for testability.
int at all since it assumes everything of type int in your project is referring to the ID of a table.Also, as a rule of thumb, if you're using strings that contain structural metadata about your objects, it's generally a sign you might want to rethink your approach.
Instead, I would find a way to apply an interface to your tables that have this structure, so you could then make an extension method for that interface, or a method that takes in an instance that implements that interface. That way you don't have to rely on strings at all.
If you are really committed to having a method that finds a value based on an int and type inputs, I would change the method to be a static, non-extension method, passing in the int and type.
I also came up with this alternative solution. Although it doesn't behave the same as your original example, you might benefit by using a type parameter so you get a strongly-typed entity returned by your method, which your code will know has a "Title" property:
public static TEntity GetEntityById(int id)
{
TEntity entity = null;
//a using is a try finally. you have stuff you want to execute in a finally so I simplified.
try
{
MyDataContext dc = new MyDataContext();
// match and select record using "id"
entity = dc.GetTable().Where(string.Format("Id.Equals({0})", id)).Cast().FirstOrDefault(); //not sure if Cast is redundant or not
}
finally
{
return entity;
}
}
//consuming code
string myTitle = GetEntityById(222).Title;I also noticed you are instantiating a datacontext in this method--you might want to either pass it in or make this an extension method on your datacontext for testability.
Code Snippets
public static TEntity GetEntityById<TEntity>(int id)
{
TEntity entity = null;
//a using is a try finally. you have stuff you want to execute in a finally so I simplified.
try
{
MyDataContext dc = new MyDataContext();
// match and select record using "id"
entity = dc.GetTable<TEntity>().Where(string.Format("Id.Equals({0})", id)).Cast<TEntity>().FirstOrDefault(); //not sure if Cast<TEntity> is redundant or not
}
finally
{
return entity;
}
}
//consuming code
string myTitle = GetEntityById<MyEntity>(222).Title;Context
StackExchange Code Review Q#86797, answer score: 3
Revisions (0)
No revisions yet.