(注意:在标题中可能有一个比“动态”更好的词,但我想不出一个。)
我有一个包含多个自引用表的数据库。一个例子如下:
+----------+
| Category |
+----+-----+-+-----------+
| id | title | parent_id |
+----+-------+-----------+
其中parent_id
是同一个表中id
的外键,因此类别可以嵌套在(理论上)无限级别中。
以下是该表的示例数据:
Animal
|- Fish
| |- Shark
| \- Trout
\- Mammal
|- Cat
\- Dog
Plant
|- Tree
| |- Fir
| \- Palm
\- Vegetable
|- Cabbage
\- Lettuce
目前使用SqlConnection
个对象在数据库上执行查询的.NET项目可以将上面的内容呈现为“扁平”字符串,如下所示:
Animal
Animal > Fish
Animal > Fish > Shark
Animal > Fish > Trout
Animal > Mammal
Animal > Mammal > Cat
Animal > Mammal > Dog
Plant
Plant > Tree
Plant > Tree > Fir
Plant > Tree > Palm
Plant > Vegetable
Plant > Vegetable > Cabbage
Plant > Vegetable > Lettuce
它通过使用递归数据库函数来执行此操作,该函数通过获取其ID来返回类别的“完整标题”。查询的SELECT
列表及其ORDER BY
子句中都使用了此函数的结果:
select Category.*, dbo.GetFullCategoryName(Category.id) as full_title
from Category
order by dbo.GetFullCategoryName(Category.id)
使用Entity Framework和Linq进行相同操作的最佳方式是什么?
该解决方案仍然可以使用数据库函数来获取完整的标题字符串,如果这有用的话。
我尝试通过向Model类添加[NotMapped]
字段来模拟这一点,该类查询DbSet并执行数据库函数的等效操作,但此字段不能用于Linq查询中的排序。 / p>
当然,我仍然可以获得一个无序列表,然后使用额外的代码重新排序此列表,但是我想知道是否有一种“更清洁”的方法来做同样的事情。
答案 0 :(得分:0)
我找到了一种方法,可以使用数据库中的视图。
有问题的视图包含每个类别的ID以及它的完整标题,它使用上述功能获得。
CREATE VIEW [dbo].[CategoryFullTitle]
AS
SELECT id, dbo.GetFullCategoryName(id) AS full_title
FROM dbo.Category
在EF中使用单独的类(CategoryFullTitle)映射到该视图,而Category类包含一个这样的对象,使用其ID作为外键。
[Table("CategoryFullTitle")] // The view's name
internal class CategoryFullTitle
{
[Key]
public Guid Id { get; set; }
[Column("full_title")]
public string Text { get; set; }
}
[Table("Category")]
internal class Category
{
[Key]
public Guid Id { get; set; }
/* ... */
[ForeignKey(nameof(Id))]
public virtual CategoryFullTitle FullTitle { get; set; }
}
Linq可以通过" category.FullTitle.Text"然后可以使用Category和Category对象来添加和更新数据库中的行,如果使用而不是表的视图,这将无法实现。