(22)ASP.NET Core EF创建模型(索引、备用键、继承、支持字段)

1.索引

比奇中文网 https://www.biqi.org/

索引是跨多个数据存储区的常见概念。尽管它们在数据存储中的实现可能会有所不同,但也可用于基于列(或一组列)更高效地进行查找。

1.1约定

按照约定,将在用作外键的每个属性(或一组属性)中创建索引。

1.2数据批注

不能使用数据批注创建索引。

1.3Fluent API

您可以使用熟知的API来指定单个属性的索引。默认情况下,索引不是唯一的。

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>()
            //配置索引
            .HasIndex(b => b.Url);
    }
}
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
}

您还可以指定索引应是唯一的,这意味着对于给定的属性,不能有两个实体具有相同的值。

modelBuilder.Entity<Blog>()
.HasIndex(b => b.Url)
.IsUnique();

您还可以为多个列指定索引。

class MyContext : DbContext
{
    public DbSet<Person> People { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Person>()
            .HasIndex(p => new { p.FirstName, p.LastName });
    }
}
public class Person
{
    public int PersonId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

2.备用键

备用键与主键相对,用作每个实体实例的备用唯一标识符。备用键可用作关系的目标。使用关系数据库时,这将映射到备用键列上的唯一索引/约束和引用列的一个或多个外键约束的概念。系统通常会在需要时为你引入备用键,你无需手动配置它们。

2.1约定

按照约定,系统将在识别属性(不是主键)时为你引入备用键,充当关系的目标。

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Post>()
            .HasOne(p => p.Blog)
            .WithMany(b => b.Posts)
            .HasForeignKey(p => p.BlogUrl)
            .HasPrincipalKey(b => b.Url);
    }
}
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
    
    public List<Post> Posts { get; set; }
}
public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    //备用键
    public string BlogUrl { get; set; }
    public Blog Blog { get; set; }
}
2.2数据注释

不能使用数据注释配置备用键。

2.3Fluent API

你可以使用熟知的API将单个属性配置为备用密钥。

class MyContext : DbContext
{
    public DbSet<Car> Cars { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Car>()
            //配置为备用密钥
            .HasAlternateKey(c => c.LicensePlate);
    }
}
class Car
{
    public int CarId { get; set; }
    public string LicensePlate { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
}
你还可以使用熟知的API将多个属性配置为备用密钥(称为复合备用键)。
class MyContext : DbContext
{
    public DbSet<Car> Cars { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Car>()
            //配置为备用密钥
            .HasAlternateKey(c => new { c.State, c.LicensePlate });
    }
}
class Car
{
    public int CarId { get; set; }
    public string State { get; set; }
    public string LicensePlate { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
}

3.继承

EF模型中的继承用于控制如何在数据库中表示实体类中的继承。

3.1约定

按照约定,由数据库提供商确定如何在数据库中表示继承。有关如何使用关系数据库提供程序来处理此情况的详细说明。如果模型中显式包括两个或更多个继承类型,则EF仅会设置继承。EF不会扫描模型中未包含的基类型或派生类型。可以通过为继承层次结构中的每个类型公开DbSet,在模型中包含类型。

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<RssBlog> RssBlogs { get; set; }
}
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
}
public class RssBlog : Blog
{
    public string RssUrl { get; set; }
}

如果不想公开层次结构中一个或多个实体的DbSet,可以使用熟知的API来确保它们包含在模型中。如果不依赖约定,则可以使用HasBaseType显式指定基类型。

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<RssBlog>().HasBaseType<Blog>();
    }
}

4.支持字段

支持字段允许EF读取和写入字段,而不是属性。当使用类中的封装来限制或通过应用程序代码对数据访问进行限制时,这可能很有用,但在不使用这些限制的情况下,应从数据库中读取或写入值。

4.1约定

按照约定,将发现以下字段作为给定属性的支持字段(按优先级顺序列出)。仅为模型中包含的属性发现字段。

public class Blog
{
    private string _url;
    public int BlogId { get; set; }
    public string Url
    {
        get { return _url; }
        set { _url = value; }
    }
}

配置了支持字段后,当从数据库具体化实体实例(而不是使用属性资源库)时,EF将直接写入该字段。如果EF需要在其他时间读取或写入值,则它将使用属性(如果可能)。例如,如果EF需要更新某个属性的值,则它将使用属性setter(如果已定义)。如果该属性为只读,则它将写入字段。

4.2数据注释

不能通过数据批注配置支持字段。

4.3Fluent API

你可以使用熟知的API来配置属性的支持字段。

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>()
            .Property(b => b.Url)
            .HasField("_validatedUrl");
    }
}
public class Blog
{
    private string _validatedUrl;
    public int BlogId { get; set; }
    public string Url
    {
        get { return _validatedUrl; }
    }
    public void SetUrl(string url)
    {
        using (var client = new HttpClient())
        {
            var response = client.GetAsync(url).Result;
            response.EnsureSuccessStatusCode();
        }
        _validatedUrl = url;
    }
}
4.3.1控制何时使用字段

可以配置EF何时使用字段或属性。有关支持的选项,请参阅PropertyAccessMode枚举。

modelBuilder.Entity<Blog>()
    .Property(b => b.Url)
    .HasField("_validatedUrl")
    .UsePropertyAccessMode(PropertyAccessMode.Field);
4.3.2没有属性的字段

你还可以在你的模型中创建一个概念属性,该属性在实体类中不具有相应的CLR属性,而是使用字段来存储实体中的数据。这不同于阴影属性,其中的数据存储在更改跟踪器中。如果实体类使用方法获取或设置值,通常会使用此方法。可以在Property(...) API中为EF指定字段的名称。如果没有具有给定名称的属性,则EF将查找字段。

class MyContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>()
            .Property("_validatedUrl");
    }
}
public class Blog
{
    private string _validatedUrl;
    public int BlogId { get; set; }
    public string GetUrl()
    {
        return _validatedUrl;
    }
    public void SetUrl(string url)
    {
        using (var client = new HttpClient())
        {
            var response = client.GetAsync(url).Result;
            response.EnsureSuccessStatusCode();
        }
        _validatedUrl = url;
    }
}

您还可以选择为属性指定名称,而不是字段名称。然后,在创建模型时使用此名称,最值得注意的是,该名称将用于在数据库中映射到的列名称。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property<string>("Url")
        .HasField("_validatedUrl");
}

如果实体类中没有属性,则可以在LINQ查询中使用EF.Property(...)方法来引用概念上是模型的一部分的属性。

var blogs = db.blogs.OrderBy(b => EF.Property<string>(b, "Url"));


参考文献:
索引
备用键
继承
支持字段

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CSDN IT狂飙上传的代码均可运行,功能ok的情况下才上传的,直接替换数据即可使用,小白也能轻松上手 【资源说明】 基于MATLAB实现的数字调制就是把数字基带信号的频谱搬移到高频处,形成适合在信道中传输的带通信号基本的数字调制方式有振幅控(ASK)、频移控(FSK)、绝对相移控(PSK)、相对(差分)相移控(DPSK)在接收端可以基于想干解调或非相干解调还原数字基带信号+使用说明文档 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2020b;若运行有误,根据提示GPT修改;若不会,私信博主(问题描述要详细); 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可后台私信博主; 4.1 期刊或参考文献复现 4.2 Matlab程序定制 4.3 科研合作 功率谱估计: 故障诊断分析: 雷达通信:雷达LFM、MIMO、成像、定位、干扰、检测、信号分析、脉冲压缩 滤波估计:SOC估计 目标定位:WSN定位、滤波跟踪、目标定位 生物电信号:肌电信号EMG、脑电信号EEG、心电信号ECG 通信系统:DOA估计、编码译码、变分模态分解、管道泄漏、滤波器、数字信号处理+传输+分析+去噪、数字信号调制、误码率、信号估计、DTMF、信号检测识别融合、LEACH协议、信号检测、水声通信 5、欢迎下载,沟通交流,互相学习,共同进步!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值