如何在自引用表中获得给定以下路由别名的最后一个类别
本文关键字:路由 别名 最后一个 自引用 | 更新日期: 2023-09-27 18:07:13
我的问题解决像这样一个代码;
string permalink = "computers/hp/computers"; //example for similarity
List<string> aliases = permalink.Split('/').ToList();
Category cat = db.Categories.SingleOrDefault(c => c.Alias == aliases.First());
aliases.Remove(aliases.First());
foreach (string alias in aliases)
{
cat = cat.Categories.SingleOrDefault(c => c.Alias == alias);
}
return cat;
但这是发送许多查询..
我怎么做一个时间?
如果我明白你想要什么,你可以使用Enumerable.Aggregate
方法。您必须从包含所有db.Categories
的"根"类别开始。这很容易模拟。试试这个:
var aliases = permalink.Split('/');
var category = new Category // start with a 'root' category
{
Id = 0,
Categories = db.Categories
};
var cat = aliases.Aggregate(category, (c, a) => c.Categories.SingleOrDefault(x => x.Alias == a));
首先,如果类别表很小,有时最好只是抓取整个表并在内存中进行选择(可能使用p.w.s.g的答案)。
如果表很大,那么存储过程可能比Linq更好。
但是,如果你真的想在Linq中这样做,那么我认为唯一的方法是反复添加一个连接到同一个表。
下面假设您的关系是在名为ParentID和Id的字段之间。我还更改了字符串permalink,以便更好地说明顺序。
首先需要一个小的辅助类
public class Info
{
public Category category;
public int? recordID;
}
那么你的主代码
string permalink ="computers1/hp/computers2";
var aliases = permalink.Split('/');
var query = dc.Categories.Where(r=>r.Alias == aliases[aliases.Length-1])
.Select(r=> new Info { category = r, recordID = r.ParentID});
for(int i = aliases.Length -2 ; i >= 0; i--)
{
string alias = aliases[i];
query = query.Join(dc.Categories ,
a => a.recordID , b => b.Id , (a,b) => new { a , b} )
.Where(r=>r.b.Alias == alias)
.Select(r=> new Info { category = r.a.category, recordID = r.b.ParentID});
}
return query.SingleOrDefault().category;
正如您所看到的,join的lambda语法(恕我直言)非常可怕,我通常会尽量避免使用它,但在这里我想不出如何避免使用它。
因为我不能测试它,它可能是完全错误的(也许我混淆了ID, ParentID或我的a和b),所以测试它并测试它的执行情况是很重要的。
我认为生成的sql应该类似于
SELECT * from Categories AS t0
INNER JOIN Categories AS t1 ON t0.ParentID = t1.id
INNER JOIN Categories AS t2 ON t1.ParentID = t2.id
WHERE t2.Alias = 'computers1'
AND t1.Alias = 'hp'
AND t0.Alias = 'computers2'
区段或别名越多,连接就越多。
现在您已经看到了所有这些,您可能想要避免使用这个方法-)
我可能只会增加你的困惑:),但让我只是抛出一个想法…
我只想说这不起作用(完全符合您的规范)-这不是解决方案,但可能会帮助您简化一些事情。
var query =
(from cat in db.Categories
where cat.Alias == "mainAalias"
from subcat in cat.Categories
where aliases.Contains(subcat.Alias)
orderby subcat.Alias descending
select subcat);
query.FirstOrDefault(); // or something
这会产生一个相对简单的查询
(如SELECT...FROM...JOIN...WHERE... AND...IN...ORDERBY...
)。
。如果你给它'cat1', 'cat2'…'cat6' -从cat1 -到cat100 -它给出'cat6'…'cat1'(我指的是别名)
然而,它有一个主要的'缺陷'与'排序' -你的规格需要排序是'别名' as they come
的顺序-这是一个有点不幸的查询。如果您能够以某种方式执行或定义一个可以转换为SQL的顺序,那么这个(或类似的)可能会起作用。
我假设-你的"别名"是按升序预先排序的订单-此查询工作。我知道他们不是这样的
。
但我认为你的想法在这里没有明确定义(以及为什么我们所有人都有问题)-思考,优化-简化您的需求-并让您的c#层帮助,例如通过预排序。
你也可以尝试某种形式的"分组"每只猫。别名等-但我认为同样的"排序问题"仍然存在。