我正在尝试为我的模型创建一个通用仓库。目前,我有三个不相关的不同模型(联系人、笔记、提醒)。
class Repository<T> where T:class
{
public IQueryable<T> SearchExact(string keyword)
{
//Is there a way i can make the below line generic
//return db.ContactModels.Where(i => i.Name == keyword)
//I also tried db.GetTable<T>().Where(i => i.Name == keyword)
//But the variable i doesn't have the Name property since it would know it only in the runtime
//db also has a method ITable GetTable(Type modelType) but don't think if that would help me
}
}
在 MainViewModel 中,我这样调用 Search 方法:
Repository<ContactModel> _contactRepository = new Repository<ContactModel>();
public void Search(string keyword)
{
var filteredList = _contactRepository.SearchExact(keyword).ToList();
}
解决方案:
最终选择了Ray的动态表达式解决方案:
public IQueryable<TModel> SearchExact(string searchKeyword, string columnName)
{
ParameterExpression param = Expression.Parameter(typeof(TModel), "i");
Expression left = Expression.Property(param, typeof(TModel).GetProperty(columnName));
Expression right = Expression.Constant(searchKeyword);
Expression expr = Expression.Equal(left, right);
}
query = db.GetTable<TModel>().Where(Expression.Lambda<Func<TModel, bool>>(expr, param));
where U : T, ContactModel, NoteModel, ReminderModel
来实现我的目标吗?我在反射方面真的很弱,请您能否解释一下这部分内容? - Amsakannawhere U : T, ContactModel, NoteModel, ReminderModel
是行不通的,因为U必须同时是这三个类。你有没有注意到我给了你反射解决方案的实际代码?我不确定有什么需要解释的。var prop = typeof(T).GetProperty("Name")
在目标对象上找到一个名为“Name”的属性,并返回一个可以快速访问Name值的对象。在Where内部,prop.GetValue(i)
实际检索名称。这很简单,而且相对快速。 - Ray Burns