我有多个带有“id”组件的表。我想使用LINQ从其中一个表中获取一个具有正确LINQ-To-SQL类型的项,但只使用一个CompiledQuery。
这是一个当前有效的例子。假设DBML中定义的对象类型是“myitem”,其表是“myitems”。
var getOneItem = CompiledQuery.Compile(
(MyDataContext db, long id) => ((from i in db.myitems
where i.id == id
select i).SingleOrDefault()));
我想做这个,其中类型可以是“myitem”,“myitems2”,或者我可能感兴趣的任何表和对象类型。
var getOneItemAnyTable = CompiledQuery.Compile(
(Table tab, Type T long id) => ((from anItem in tab<T>
where anItem.id == id
select anItem).SingleOrDefault()));
我编写了这个语法,因为我不确定这里的语法是什么样的。任何想法,如果可能的话?我是否必须使用DBML来为所涉及的类型创建某种超类?
谢谢。
答案 0 :(得分:2)
而不是这样做,从实体中具有共同属性的基础实体派生所有实体(如Id)。使用POCO实现这些层将对您有所帮助。
答案 1 :(得分:1)
我很确定你不能让一个编译查询跨越多个表(如果这就是你的意思);怎么会知道在哪里看? EF通过继承(和多个表)支持这样的东西,但即使继承,LINQ-to-SQL也仅支持单表区别继承。
这个问题的核心与今天早些时候相同to this one。棘手的一点是主键,因为很难抽象地定义。其余的只是GetTable<T>
(至少有LINQ-to-SQL)。
在这种情况下,您不需要超类 - 只是获取主键的一种方法。幸运的是,我似乎记得LINQ-to-SQL提供了一种方法(不需要使用属性,这不是LINQ-to-SQL的预先请求);以下不预编译(并且未经测试),但应该非常接近:
(更新已修复并经过测试)
用法优先:
Foo foo = ctx.Get<Foo>(fooid);
Bar bar = ctx.Get<Bar>(barid);
代码:
public static TItem Get<TItem, TKey>(
this DataContext ctx, TKey key)
where TItem : class
{
var table = ctx.GetTable<TItem>();
var primaryKey = ctx.Mapping.GetMetaType(typeof(TItem))
.DataMembers.Where(
member => member.IsPrimaryKey).Single().Member.Name;
var item = Expression.Parameter(typeof(TItem), "item");
var lambda = Expression.Lambda<Func<TItem, bool>>(
Expression.Equal(
Expression.PropertyOrField(item, primaryKey),
Expression.Constant(key, typeof(TKey))),
item);
return table.Single(lambda);
}
public static TItem Get<TItem>( // common case
this DataContext ctx, int key)
where TItem : class
{
return Get<TItem, int>(ctx, key);
}
public static TItem Get<TItem>( // common case
this DataContext ctx, string key)
where TItem : class
{
return Get<TItem, string>(ctx, key);
}
我会看是否能找到预编译的方法......