【Entity Framework】你知道如何处理无键实体吗

【Entity Framework】你知道如何处理无键实体吗

文章目录

  • [【Entity Framework】你知道如何处理无键实体吗](#【Entity Framework】你知道如何处理无键实体吗)

一、概述

Entity Framework 除了常规实体类型外,EF Core模型还可以包含无键实体类型,可用于对不包含键值的数据执行数据库查询。

二、定义无键实体类型

可按如下定义无键实体类型:

数据注释
c# 复制代码
[Keyless]
public class BlogPostsCount
{
    public string BlogName{get;set;}
    public int PostCount{get;set;}
}
  • Fluent API
c# 复制代码
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<BlogPostsCount>()
        .HasNoKey();
}

三、无键实体类型特征

无键实体类型支持与常规实体类型相同的多个映射功能,例如继承映射和导航属性。在关系存储上,它们可以通过Fluent API方法或数据注释来配置目标数据库对象和列。

但是,它们不同于常规实体类型,因为他们:

  • 不能定义键

  • 永远不会对DbContext中的更改进行跟踪,因此不会对数据库进行插入,更新或删除这些操作

  • 绝不会被约定发现

  • 仅支持导航映射功能的子集,具体如下:

    • 它们永远不能充当关系的主体端
    • 它们可能没有指向从属实体的导航
    • 它们只能包含指向常规实体的引用导航属性
    • 实体不能包含无键实体类型的导航属性
  • 需要配置 [Keyless] 数据注释或 .HasNoKey() 方法调用

  • 可以映射到定义查询。 定义查询是在模型中声明的查询,它充当无键实体类型的数据源

  • 可以具有层次结构,但必须映射为 TPH

  • 不能使用表拆分或实体拆分

四、无键实体使用场景

无键实体类型的一些主要使用场景包括:

  • 充当SQL查询的返回类型
  • 映射到不包含主键的数据库视图
  • 映射到未定义主键的表
  • 映射到模型中定义的查询

五、无键实体使用场景

可以使用 ToTableToView Fluent API 将无键实体类型映射到数据库对象。 从 EF Core 的角度来看,此方法中指定的数据库对象是一个视图,这意味着它将被视为只读查询源,并且不能作为更新、插入或删除操作的目标。 但是,这并不意味着数据库对象实际上必须是数据库视图。 它也可以是将被视为只读的数据库表。 相反,对于常规实体类型,EF Core 假设 ToTable 方法中指定的数据库对象可以作为表,这意味着它可用作查询源,但也可作为更新、删除和插入操作的目标。 事实上,可以在 ToTable 中指定数据库视图的名称,只要该视图配置为可在数据库上更新,一切都应能正常运行。

六、无键使用示例

6.1 定义一个简单的Blog和Post模型:

c# 复制代码
public class Blog
{
    public int BlogId { get; set; }
    public string Name { get; set; }
    public string Url { get; set; }
    public ICollection<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public int BlogId { get; set; }
}

6.2 定义一个简单数据库视图

c# 复制代码
db.Database.ExecuteSqlRaw(
    @"CREATE VIEW View_BlogPostCounts AS
                SELECT b.Name, Count(p.PostId) as PostCount
                FROM Blogs b
                JOIN Posts p on p.BlogId = b.BlogId
                GROUP BY b.Name");

6.3 定义一个类来保存数据库视图的结果

c# 复制代码
public class BlogPostsCount
{
    public string BlogName { get; set; }
    public int PostCount { get; set; }
}

6.4 使用HasNoKey API在OnModelCreating中配置无键实体类型

c# 复制代码
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder
        .Entity<BlogPostsCount>(
            eb =>
            {
                eb.HasNoKey();
                eb.ToView("View_BlogPostCounts");
                eb.Property(v => v.BlogName).HasColumnName("Name");
            });
}

6.5 配置DbContext以包含DbSet<T>

c# 复制代码
public DbSet<BlogPostsCount> BlogPostCounts { get; set; }

6.7 采用标准方式查询数据库视图

c# 复制代码
var postCounts = db.BlogPostCounts.ToList();
foreach (var postCount in postCounts)
{
    Console.WriteLine($"{postCount.BlogName} has {postCount.PostCount} posts.");
    Console.WriteLine();
}

七、总结

无键主要应用在SQL、视图、存储过程的查询,在制作报表时,应用比较多。

相关推荐
博一波13 分钟前
Redis 集群:连锁银行的 “多网点智能协作系统”
数据库·redis·缓存
anlpsonline18 分钟前
安全产业 出海行动 | 安贝斯受邀参加第六届非传统安全(杭州)国际论坛:靠近国际前沿 拓宽国际视野
microsoft
HashData酷克数据19 分钟前
官宣:Apache Cloudberry (Incubating) 2.0.0 发布!
数据库·开源·apache·cloudberry
秋难降19 分钟前
SQL 索引突然 “罢工”?快来看看为什么
数据库·后端·sql
TDengine (老段)1 小时前
TDengine 时间函数 TODAY() 用户手册
大数据·数据库·物联网·oracle·时序数据库·tdengine·涛思数据
码界奇点1 小时前
KingbaseES一体化架构与多层防护体系如何保障企业级数据库的持续稳定与弹性扩展
数据库·架构·可用性测试
悟乙己1 小时前
数据科学家如何更好地展示自己的能力
大数据·数据库·数据科学家
皆过客,揽星河2 小时前
mysql进阶语法(视图)
数据库·sql·mysql·mysql基础语法·mysql进阶语法·视图创建修改删除
_oP_i2 小时前
WinForms 项目里生成时选择“首选目标平台 32 位导致有些电脑在获取office word对象时获取不到
c#·office