为 Linq (2Sqlite) 编写谓词
本文关键字:谓词 2Sqlite Linq | 更新日期: 2023-09-27 18:33:31
>我有一个以下问题 - 有限的ORM强加了基础设施与域对象的耦合。
请注意,这是一个Windows应用商店应用程序,反射API与标准.Net不同。
例如,我必须像这样手动实现导航属性(代码中的关系)(假设我有一个包含一对多子章节集合的书籍聚合):
List<Chapters> Chapters
{get {return db.Query<Chapters>.Where(b => b.BookId == this.Id);}}
我想减少这种耦合是通用扩展方法的手段,它将为父实体检索子实体,例如
IEnumerable<T> GetChildren<TParent,TChild>(this TParent parent)
where TParent, TChild : Entity
我可以假设所有实体都有一个 Id 主键属性,外键由父实体名称和 Id("BookId")组成
如何实现数据库的谓词。查询。在此扩展方法中,假设此参数是父实体的 Linq 方法在哪里?
类似的东西
(简化版本):
public static TChild GetHierarchyChild<TParent, TChild>(this TParent parent)
{
var pType = typeof(TParent);
var chType = typeof(TChild);
var chPropInfo = pType
.GetProperties()
.FirstOrDefault(p => p.PropertyType == chType);
if (chPropInfo == null)
{
return default(TChild);
}
return (TChild)chPropInfo.GetValue(parent);
}
public class A
{
public IEnumerable<B> Bs
{
get
{
return new[] { new B(1) };
}
}
}
public class B
{
public B(int id)
{
Id = id;
}
public int Id { get; protected set; }
}
举个例子:
var a = new A();
var bs = GetHierarchyChild<A, IEnumerable<B>>(a);
bs.ToString();
这对我有用,但不幸的是,Sqlite-Net在其Linq2Db实现中不支持这种类型的表达式。它在最后一个语句上崩溃。我将不得不将此部分重写为 SQL。
private const string keyName = "Id";
public static async Task<IEnumerable<TChild>> GetChildrenAsync<TParent, TChild>(this TParent parent)
where TParent : Entity
where TChild : Entity, new()
{
var parentType = typeof (TParent);
var parentName = parentType.GetTypeInfo().Name;
var parentKeyValue = (int)parentType.GetRuntimeProperty(keyName).GetValue(parent);
var foreignKeyName = String.Format("{0}{1}", parentName, keyName);
var childProperty = typeof(TChild).GetRuntimeProperty(foreignKeyName);
var connection = DbConnection.Current;
var query = connection.Table<TChild>().Where(c => (int)childProperty.GetValue(c) == parentKeyValue);
return await query.ToListAsync();
}