我使用 BLToolkit 已经有一段时间了,最近我一直在按照作者的建议测试 Linq2Db。
我已经能够重新创建为 BLToolkit 所做的大部分自动化操作,但我正在努力创建一个标准结构来查询具有多个表连接和列子集的数据。实际上,我们当前使用的方法是相当手动的,我正在尝试使用更自动化的方法,使我们能够使用 LINQ 来为我们的客户端上的 linq2db 框架提供的服务。
让我们从一个简化的例子开始。
Table HEADER
Column ID
Column Name
Table LINE
Column ID
Column Header_Id
Column Element_Id
Table ELEMENT
Column ID
Column Name
有了这些表,我成功地生成了 POCO 类并单独进行了查询并填充了与 Linq2Db 的关联。现在我假装是查询这样的事情:
SELECT
H.ID AS Header_Id,
H.Name AS Header_Name,
L.ID AS Line_Id
E.ID AS Element_Id
E.Name AS Element_Name
FROM HEADER H JOIN LINE L ON H.ID = L.Header_Id
JOIN ELEMENT E ON L.Element_Id = E.ID
鉴于我已经设置了这样的课程:
public class FullOrderData
{
public int Header_Id { get; set; }
public string Header_Name { get; set; }
public int Line_Id { get; set; }
public int Element_Id { get; set; }
public string Element_Name { get; set; }
}
我没有问题像这样查询它:
using(var db = new MyTestDb())
{
var orderData = db.Query<FullOrderData>(selectQuery).ToList();
}
现在我想要实现什么以及到目前为止我已经尝试过什么:
第一步:自动查询
我想以某种方式将查询“嵌入”到类的元数据中,例如:
选项1
[JoinObjectQuery("SELECT ....")]
public class FullOrderData
{
....
}
public static class DataConnectionExtensions
{
public static IEnumerable<T> QueryJoinObject<T>(this DataConnection db)
{
//search for JoinObjectQuery attribute and invoke db.Query<T>(joinObjectQueryAttribute.Query)
}
}
选项 2
public interface IJoinObject
{
string BaseQuery { get; }
}
public class FullOrderData : IJoinObject
{
public string BaseQuery => "SELECT....";
}
public static class DataConnectionExtensions
{
public static IEnumerable<T> QueryJoin<T>(this DataConnection db) where T : IJoinObject, new()
{
return db.Query<T>(New<T>.Instance().BaseQuery)
}
}
到目前为止一切都很好......或者不是这样,因为第一个选项迫使开发人员知道在哪里调用 db.Query() 以及何时调用 db.QueryJoinObject() 和第二个强制创建一个额外的虚拟接口并创建每次一个新实例(尽管可以实现缓存)
第二步:在这些对象上使用 Linq to SQL
这就是科幻小说对我来说开始的地方,因为我不知道如何处理这个问题。
显然,如果我执行:
db.Query<FullOrderData>().Where(x => x.Header_Id == 1).ToList()
linq2sql 执行完整的选择查询,然后将 Where 应用于已映射的对象。这是我无法承受的真正的性能痛苦。
所以,我正在寻找一种以某种方式修饰类 linq2db 可以生成与 linq 语句相对应的 SQL 的方法。
你对我在第一步暴露的内容有什么看法?关于第二步选择什么方向的任何建议?
提前致谢。