• Entity Framework Core


    阴影(Shadow property)和索引器(Indexer property)属性

      阴影属性,是指不在.net实体类中定义、但在EF核心模型中为该实体类型定义的属性。这些属性的值和状态纯粹在更改跟踪器中维护。当数据库中存在不应该在映射实体类型上公开的数据时,阴影属性非常有用。(相当于数据库表中的一些列,不需要在实体类中映射,但是可以在EF模型中定义、追踪、赋值等)

      索引器属性,是实体类型属性,由.net实体类的索引器支持。可以在类型实例上使用索引器对其进行访问。还允许向实体类型添加其他属性,而无需更改CLR类

      本节中,出现了一些和“关系”相关的概念,比如导航。关系,定义了两个实体类之间的关系(一对一、一对多、多对多),它对应着关系型数据库中的外键的概念。具体,可参考下一节内容。

    1、外键阴影属性 Foreign key shadow properties

      阴影属性,最常用于外键属性,其中两个实体之间的关系由数据库中的外键值表示,但使用实体类型之间的导航属性在实体类型上管理关系。

      约定:当发现关系存在但是在依赖实体类中找不到外键属性时,EF就会引入一个阴影属性。

      该属性将被命名 <navigation property name><principal key property name> (用在依赖实体上的、且指向主实体的导航来命名);如果主体键属性名称包含导航属性的名称,则该名称将只是 <principal key property name> 。 如果依赖实体上没有导航属性,则会在其位置使用主体类型名称。示例中,将导致将BlogId阴影属性引入到Post实体中:

    class MyContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }
    }
    
    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; }
      // 由于没有CLR属性(上一行)保存此关系的外键,因此将创建一个影子属性。
       public Blog Blog { get; set; } }

    2、配置阴影属性

      使用Fluent API配置阴影属性。示例,一旦您调用了Property的字符串重载方法,您就可以为其他属性链接任何配置调用;由于Blog没有名为LastUpdated的CLR属性,因此创建了一个阴影属性:

    class MyContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
    
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Blog>()
                .Property<DateTime>("LastUpdated");
        }
    }
    
    public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }
    }

      如果提供给Property方法的参数名与现有属性(影子属性或实体类上定义的属性)的名称匹配,则代码将配置该现有属性,而不是引入新的影子属性。

    3、访问阴影属性

      可以通过 API 获取和更改影子属性值 ChangeTracker :

    context.Entry(myBlog).Property("LastUpdated").CurrentValue = DateTime.Now;

      可以通过静态方法在 LINQ 查询中引用影子属性 EF.Property :

    var blogs = context.Blogs
        .OrderBy(b => EF.Property<DateTime>(b, "LastUpdated"));

      在无跟踪查询后,不能访问阴影属性,因为更改跟踪器不跟踪返回的实体。

    4、配置索引器属性

      您可以使用Fluent API来配置索引器属性。一旦调用了方法IndexerProperty,就可以为其他属性链接任何配置调用。在下面的示例中,在Blog类型的LastUpdated属性上定义了一个索引器,它将用于创建索引器属性:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Blog>().IndexerProperty<DateTime>("LastUpdated");
    }

      如果提供给方法的名称 IndexerProperty 与现有索引器属性的名称匹配,则代码将配置该现有属性。 如果实体类型具有由实体类的属性支持的属性,则会引发异常,因为索引器属性只能通过索引器访问。

    5、属性包实体类型 Property bag entity types

      这是EF Core 5 的新特性。

      仅包含索引器属性的实体类型称为 "属性包实体类型"。 这些实体类型没有影子属性,而 EF 将创建索引器属性。 目前仅 Dictionary<string, object> 支持作为属性包实体类型。 它必须配置为具有唯一名称的共享实体类型,并且 DbSet 必须使用调用来实现相应的属性 Set :

    class MyContext : DbContext
    {
        public DbSet<Dictionary<string, object>> Blogs => Set<Dictionary<string, object>>("Blog");
    
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.SharedTypeEntity<Dictionary<string, object>>("Blog", bb =>
            {
                bb.Property<int>("BlogId");
                bb.Property<string>("Url");
                bb.Property<DateTime>("LastUpdated");
            });
        }
    }
  • 相关阅读:
    设计模式----工厂模式
    设计模式----简单工厂
    log4net使用详解
    link/Extended dependency 无法显示连接
    Abp框架之执行Update-Database 命令系列错误
    Index API
    使用Java客户端操作elasticsearch(二)
    elasticsearch之分词插件使用
    使用Java Low Level REST Client操作elasticsearch
    js如何获取隐藏的元素的高度
  • 原文地址:https://www.cnblogs.com/hiwuchong/p/14147548.html
Copyright © 2020-2023  润新知