Error message here!

Hide Error message here!

忘记密码?

Error message here!

请输入正确邮箱

Hide Error message here!

密码丢失?请输入您的电子邮件地址。您将收到一个重设密码链接。

Error message here!

返回登录

Close

asp.net core系列 25 EF模型配置(隐藏属性)

花阴偷移 2019-02-17 11:19:00 阅读数:166 评论数:0 点赞数:0 收藏数:0

一. 隐藏属性概述

隐藏属性也叫影子属性,该属性不是在.net实体类中定义的属性,而是在EFCore模型中为该实体类型定义的属性。这些属性的值和状态完全在变更跟踪器中维护。它有二个功能:(1)当数据库中某些字段不想映射到实体类上公开的属性时,隐藏属性非常有用。(2)隐藏属性通常是用于外键属性,其中两个实体之间的关系由数据库中的外键值表示,但是两个实体关系是使用实体类型之间的导航属性进行管理(这个在下面约定中讲到)。

隐藏属性值可以通过ChangeTracker API获取和更改:

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

下面讲第一个功能:当数据库中某些字段不想映射到实体类上公开的属性时,隐藏属性非常有用

1.1 配置隐藏属性

不能通过数据注释来创建隐藏属性,只能通过 Fluent API 来创建, Blog实体中没有映射LastUpdated公开属性,但创建了隐藏属性。

class BloggingContext: 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; }
}

1.2 设置隐藏属性值

在新增时blog一条数据时,通过ChangeTracker API可以为隐藏属性LastUpdated设置时间值,提交到数据库表中。

 [HttpPost]
public async Task<IActionResult> Create([Bind("Url")] Blog blog)
{
if (ModelState.IsValid)
{
//设置隐藏属性的值
BloggingContext.Entry(blog).Property("LastUpdated").CurrentValue = DateTime.Now;
BloggingContext.Add<Blog>(blog);
await BloggingContext.SaveChangesAsync();
}
return View();
}

1.3 读取blog表数据

可以通过 LINQ 查询中引用隐藏属性EF.Property静态方法,通过隐藏属性LastUpdated排序,读取blog集合数据。

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

 

二.约定

下面讲第二个功能,隐藏属性通常用于外键属性。当二个实体存在主从关系,但在依赖实体类中找不到外键属性时,默认是通过"约定"来创建隐藏外键属性的。隐藏外键属性将被命名为<navigation property name><principal key property name>。以下面的示例来说:post依赖实体中包含了隐藏的外键属性 “BlogId ”。

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 Blog Blog { get; set; }
}

下面简单测试下,通过初例化一个的Post依赖实体,查看该实例中是否包含了BlogId 外键隐藏属性,通过ChangeTracker API来获取,使用断点查看该BlogId 隐藏属性确实存在,只是在Post实体上是非公开的外键属性:

 public void OnGet()
{
object obj = _bloggingContext.Entry(new Post()).Property("BlogId").CurrentValue;
}
_bloggingContext.Entry(new Post()).Property("BlogId")
{Microsoft.EntityFrameworkCore.ChangeTracking.PropertyEntry}
CurrentValue: null
EntityEntry: {Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalMixedEntityEntry}
InternalEntry: {Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalMixedEntityEntry}
IsModified: false
IsTemporary: false
Metadata (Microsoft.EntityFrameworkCore.ChangeTracking.MemberEntry): {Property: Post.BlogId (no field, Nullable<int>) Shadow FK Index 1 1 1 0 1}
Metadata: {Property: Post.BlogId (no field, Nullable<int>) Shadow FK Index 1 1 1 0 1}
OriginalValue: null

参考文献:

官方文档:EF 隐藏属性

 

版权声明
本文为[花阴偷移]所创,转载请带上原文链接,感谢
https://www.cnblogs.com/MrHSR/p/10383576.html

编程之旅,人生之路,不止于编程,还有诗和远方。
阅代码原理,看框架知识,学企业实践;
赏诗词,读日记,踏人生之路,观世界之行;