petapoco是否有能力实现以下目标: 1.在一个查询中无限连接 2.一个查询中无限制的一对多关系
我看过PetaPOCO,看起来它不能做超过4个连接,最长的签名看起来像: db.Query< T1,T2,T3,T4>
似乎它支持一对多关系,但仅适用于一个复合对象,如下所示: db.FetchOneToMany< T1,T2>其中T2是T1的外键
我正在测试那里的一些微型ORM以坚持最好的。你知道其中任何一个可以处理这些情况吗?如果没有微观ORM支持这种情况,你如何处理如下的对象:
class A
{
List<B> member1;
List<C> member2;
Z member3; //Composit object
Z1 member4; //Composit object
Z2 member5; //Composit object
Z3 member6; //Composit object
Z4 member7; //Composit object
}
然后更复杂的是,如果成员一(B型)本身有一些复合对象呢?如果我们有以下内容怎么办?
class B
{
G member0;
}
请不要提出多次点击数据库的解决方案,因为当对象变得有点复杂时,它会变得太多了。
哦,我也知道另一种解决无限连接情况的方法是创建一个非常扁平的对象,将所有字段组合在一起。它根本不是一个优雅的解决方案。
答案 0 :(得分:4)
T1..T $ Query()重载全部传递给主Query(.. Type [] ..)方法。你可以自己添加更多的Query()重载来处理更多的T参数,或者在Type数组中传递你需要的所有类型(这是T1-T4函数的作用):
Query<TRet>( new Type[]{typeof(Poco1), typeof(Poco2), typeof(Poco3), typeof(Poco4), typeof(Poco5)}, null, sql, args);
您可以拥有多个一对多关系,但Schotime是正确的,您需要非常小心回到结果集中的重复数据。编写sql查询并查看结果集,是否可以接受重复的数量?如果是这样,那么在Petapoco中有一个关联回调的概念,你可以编写一个小类来处理单个结果行中的不同pocos,并将每个poco添加到父poco的列表属性中。
我从来没有做过多次一对多,但引用了上述
“如果你加入两张以上的桌子,你需要更多的东西 复杂,但它只是上述的扩展。“
另一种选择是让一个存储过程在单个数据库请求中完成所有工作并让它返回多个结果集,我相信Schotime已经在他的petapoco分支中实现了但是我还没有使用它,所以我无法评论它是否会对此有所帮助:
http://schotime.net/blog/index.php/2011/11/20/petapoco-multiple-result-sets/
如果我完全将所有数据连接起来,那么对象就像你建议的那样复杂和嵌套,那么我会使用一个存储过程(单个数据库调用)并将其全部拼接和代码一起。只有这样我才能知道如何在Petapoco中做到这一点。但是,如果您的UI在用户单击扩展器按钮(或类似)之前未显示所有嵌套数据,那么我将在此时使用AJAX调用,而不是最初获取所有数据。
答案 1 :(得分:0)
答案是正确的,但是我从另一个论坛来到这个页面,没有人可以做到这一点,所以我想我会把我所做的事情搞得更清楚。基本上,我有以下代码:
var sql = "select * from someTable where tableId = @0";
var listOfStuff = _petapoco.Fetch<FirstType, SecondType, ThirdType, FourthType, FirstType>(new RelatorClass().MapIt, sql, idVar);
由于我需要添加第五个poco,并且所有Fetch方法最终都会导致上面在接受的答案中列出的主查询方法,我必须这样做:
var sql = "select * from someTable where tableId = @0";
Func<FirstType, SecondType, ThirdType, FourthType, FifthType, FirstType> mapIt = new RelatorClass().MapIt;
var listOfStuff = _petapoco.Query<FirstType>(new[] { typeof (FirstType), typeof (SecondType), typeof (ThirdType), typeof (FourthType), typeof(FifthType)}, mapIt, sql, idVar).ToList();
现在我可以用5个pocos查询,我没有必要修改PetaPoco代码。唯一要做的就是添加到你的关联类,这样你就可以告诉PetaPoco在哪里映射新数据,你就可以了。
答案 2 :(得分:0)
代表:
注意:您不必像这样返回 (UserActivity,int)
匿名类型,您可以返回没有括号的单个类型!我只是懒惰,不想为返回类型创建新模型。
private delegate (UserActivity, int) GetIt(int fk_AccountTypeValue, UserActivityModel ua, User u, Client c, Client_Account ca);
SQL 操作:
public List<(UserActivity,int)> SomeMethodName(int orgnizationID)
{
var sql = Sql.Builder
.Select("TOP(200) at.FK_AccountTypeValue, ua.*, u.*, c.*, ca.*")
.From("UserActivity ua")
.LeftJoin("Users u").On("u.PK_UserID = ua.FK_UserID")
.LeftJoin("Client c").On("c.FK_UserID = u.PK_UserID")
.LeftJoin("Client_Account ca").On("ca.FK_ClientID = c.PK_ClientID")
.LeftJoin("AccountType at").On("at.PK_AccountType = c.FK_AccountTypeID")
.Where("u.FK_OrganizationID =@0", orgnizationID)
.OrderBy("ua.Timestamp desc");
GetIt obj = new GetIt(youKnowIt);
var typs = new Type[]{typeof(int), typeof(UserActivityModel), typeof(User), typeof(Client), typeof(Client_Account)};
var uaList = _database.Query<(UserActivity, int)>(typs, obj, sql.SQL, sql.Arguments).ToList();
return uaList;
}
委托指向的方法:
private (UserActivity,int) youKnowIt(int fk_AccountTypeValue, UserActivityModel ua, CurrentDesk.Models.User u, CurrentDesk.Models.Client c, CurrentDesk.Models.Client_Account ca)
{
// do stuff
var uam = new UserActivity()
{
// assign stuff
};
return (uam, fk_AccountTypeValue);
}