有没有办法使用Entity Framework和Linq按动态字段排序?

时间:2016-10-27 14:38:23

标签: .net sql-server entity-framework linq tree

(注意:在标题中可能有一个比“动态”更好的词,但我想不出一个。)

我有一个包含多个自引用表的数据库。一个例子如下:

+----------+
| 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>

当然,我仍然可以获得一个无序列表,然后使用额外的代码重新排序此列表,但是我想知道是否有一种“更清洁”的方法来做同样的事情。

1 个答案:

答案 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对象来添加和更新数据库中的行,如果使用而不是表的视图,这将无法实现。