Если вы не планируете создание экземпляра своего Foo-объекта с помощью какого-либо метода извлечения из репозитория данных, это потребует динамической компиляции для добавления необходимого в ваш метод получения и установки.
Вместо этого я рекомендую вам взглянуть наДля такого шаблона
var foo = DataRepository.GetObject<Foo>(some_id);
сигнатура метода GetObject будет
public static T GetObject<T>(object id) where T: new()
. В методе GetObject вы будете размышлять над типом, найдя все его атрибуты Field и сопоставив их сфактический вызов базы данных.Это очень простой и распространенный подход, и его можно реализовать следующим образом:
public static IEnumerable<Tuple<PropertyInfo, FieldAttribute>> GetFieldAttributes<T>()
{
var properties = typeof(T).GetProperties();
foreach (var prop in properties)
{
var attribute = prop.GetCustomAttributes(typeof(FieldAttribute), true).FirstOrDefault();
if (attribute != null)
{
yield return new Tuple<PropertyInfo, FieldAttribute>(prop, attribute);
}
}
}
Теперь со списком атрибутов og вы можете создать строку типа sql
var columns = GetFieldAttributes<T>().Select(t => t.Item2.FieldName);
var sql = "SELECT "+ String.Join("," columns) +" FROM table WHERE id = "+ id;
var result = ... execute the query and return ie a datareader
Получивможет создать экземпляр Foo, заполнить его свойства и вернуть экземпляр
var instance = new T();
result.Read()
var dictionary = new Dictionary<string, object>();
// get the columns returned from database
for (int i = 0; i < reader.FieldCount; i++)
{
string fieldName = reader.GetName(i);
object value = reader.GetValue(i);
dictionary.Add(fieldName, value);
}
// bind the columns from database to the properties of our object
foreach (var c in columns)
{
var attr = c.Item2;
var value = dictionary[attr.FieldName];
if (value is DBNull)
{
value = null;
}
typeof(T).InvokeMember(c.Item1.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.SetProperty | BindingFlags.Instance, null, instance, new[] { value });
}
// return the new object with all its values filled out
return instance