【问题标题】:Is there a way to use Entity Framework and Linq to order by a dynamic field?有没有办法使用 Entity Framework 和 Linq 按动态字段排序?
【发布时间】:2016-10-27 14:38:22
【问题描述】:

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

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

+----------+
| 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 查询中的排序。

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

【问题讨论】:

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


    【解决方案1】:

    我找到了一种方法来使用数据库中的视图。

    有问题的视图具有每个类别的 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 对象来添加和更新数据库中的行,如果使用视图而不是表。

    【讨论】:

      猜你喜欢
      • 2015-05-25
      • 1970-01-01
      • 2021-02-02
      • 1970-01-01
      • 1970-01-01
      • 2022-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多