我试图通过反映泛型方法Find来获取SubSonic IActiveRecord,如下所示:
(请忽略查找MethodInfo时的第一个丑陋草案)
private T GetSavedRecord<T>(string tag) where T : IActiveRecord, ITagged
{
//Some internal caching stuff
...
MethodInfo info = typeof(T).GetMethods(BindingFlags.Static | BindingFlags.Public)
.FirstOrDefault(m => m.Name == "Find" && m.GetParameters().Count() == 1);
Expression<Func<T, bool>> predicate = e => e.Tag == tag;
T record = ((IList<T>)info.Invoke(null, new object[] { predicate })).FirstOrDefault();
return //cached record
}
ITagged只是定义了
string Tag { get; set; }
当我调用指向Find函数的MemberInfo时,我将抛出一个System.NotSupportedException,并显示以下消息:
“不支持会员'标签'”
但是,我可以使用相同的谓词在任何实际的IActiveRecord实现上调用静态Find方法。
(对于那些精通亚音速的人,我修改了.tt模板,在所有生成的类中包含ITagged接口)
我不认为这个问题与SubSonic特别相关,但我想我会提到它,以防万一。
答案 0 :(得分:3)
如果我理解正确,你基本上是在尝试针对提供者(SubSonic)创建LINQ查询,该提供者将尝试解析LINQ表达式以生成针对底层数据存储的查询。问题是,在SubSonic的世界中不存在ITagged.Tag,因此无法对其进行查询。您将需要使表达式树基于实际的T.Tag
属性而不是。
这些方面应该有效:
var tagMember = typeof(T).GetProperty("Tag");
var eParam = Expression.Parameter(typeof(T), "e");
var predicate =
Expression.Lambda<Func<T, bool>>(
Expression.Equal(
Expression.Property(eParam, tagMember),
Expression.Constant(tag)
),
eParam);