EF Core – Owned Entity Types & Complex Types
前言
EF Core 8.0 推出了 Complex Types,这篇要来介绍一下。
由于它和 Owned Entity Types 傻傻分不清楚,加上我之前也没有写过 Owned Entity Types 的文章,所以这篇就一起介绍呗。
Owned Entity Types
Owned Entity Types 本质上任然属于一种 Entity Types,只是它有一些潜规则,所以变得和普通 Entity Type 有所区别。
Owned Entity Types 在 Domain-driven design (领域驱动设计) 里被视作为 Aggregate 的实现。很遗憾,我对 DDD 一窍不通,无法用 DDD 视角去解释它。
Compare with one-to-one relationship
我们拿 one-to-one relationship 来做对比,这样就可以看出 Owned Entity Types 的特色了。
首先,做两个 Entity -- Order 和 OrderCustomerInfo
public class Order
{
public int Id { get; set; }
public OrderCustomerInfo CustomerInfo { get; set; } = null!;
public decimal Amount { get; set; }
} public class OrderCustomerInfo
{
public int Id { get; set; }
public Order Order { get; set; } = null!;
public string Name { get; set; } = "";
public string Phone { get; set; } = "";
}
它们是一对一关系
public class ApplicationDbContext() : DbContext()
{
public DbSet<Order> Orders => Set<Order>();
public DbSet<OrderCustomerInfo> OrderCustomerInfos => Set<OrderCustomerInfo>(); protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Order>(
builder =>
{
builder.ToTable("Order");
builder.Property(e => e.Amount).HasPrecision(19, 2);
builder.HasOne(e => e.CustomerInfo).WithOne(e => e.Order).HasForeignKey<OrderCustomerInfo>(e => e.Id);
}); modelBuilder.Entity<OrderCustomerInfo>(
builder =>
{
builder.ToTable("OrderCustomerInfo");
builder.Property(e => e.Name).HasMaxLength(256);
builder.Property(e => e.Phone).HasMaxLength(256);
});
}
}
接着 insert 和 query
using var db = new ApplicationDbContext(); // insert order with customer info
db.Orders.Add(new()
{
Amount = 100,
CustomerInfo = new()
{
Name = "Derrick",
Phone = "+60 16-773 7062",
},
});
db.SaveChanges(); // query
var order = db.Orders
.Include(e => e.CustomerInfo)
.First(); Console.WriteLine(order.CustomerInfo.Name); // "Derrick"
Owned Entity Types 的特性
对比 one-to-one,Owned Entity Types 有几个特性:
Owned Entity Types 没有 DbSet

OrderCustomerInfo 不是独立的 Entity,它属于 part of the Order Entity,所以它没有 DbSet。
这也导致了它不能直接被创建,下面这句是不成立的
db.OrderCustomerInfos.Add() // 'ApplicationDbContext' does not contain a definition for 'OrderCustomerInfos'
OrderCustomerInfo 需要依附在 Order 上才能一起被创建,像这样
db.Orders.Add(new()
{
Amount = 100,
CustomerInfo = new()
{
Name = "Derrick",
Phone = "+60 16-773 7062",
},
});自动 Include
没有 DbSet 自然也无法直接 query
db.OrderCustomerInfos.ToList() // 'ApplicationDbContext' does not contain a definition for 'OrderCustomerInfos'
要获取 OrderCustomerInfo 只能透过 Order。另外 Owned Entity Types 有一个特色 -- 它会自动被 Include 出来。

即便我们没有写 Include,Owned Entity Types 依然会被 eager loading 出来。
same Table

默认情况下,Owned Entity Types (OrderCustomerInfo) 会和它依附的 Entity Types (Order) 存放在同一个数据库 Table,还有 column name 会加上 prefix,这就像使用了 Table Splitting 的那样。
Id become shadow property

Owned Entity Types 任然是 Entity Types,它依然有 primary key 的概念,只是它改成了 Shadow Property,在 class 会看不见 Id。
Config Owned Entity Types



替换成这样
modelBuilder.Entity<Order>(
builder =>
{
builder.ToTable("Order");
builder.Property(e => e.Amount).HasPrecision(19, 2);
builder.OwnsOne(e => e.CustomerInfo, builder =>
{
builder.Property(e => e.Name).HasMaxLength(256);
builder.Property(e => e.Phone).HasMaxLength(256);
});
});
效果
// query
var order = db.Orders.First(); Console.WriteLine(order.CustomerInfo.Name); // "Derrick"
不需要 Include,它会自动 Include。
数据库 Order Table

OrderCustomerInfo 的属性被映射到 Order Table,而且 column name 加了 prefix "CustomerInfo" 这名字来自 Order.CustomerInfo 属性。
我们调 Entity Model 出来证实一下,Owned Entity Types 也是一种 Entity Types 而且它其实是有 Key 的。
using var db = new ApplicationDbContext();
var customerEntityType = db.Model.FindEntityType(typeof(OrderCustomerInfo))!; // Owned Entity Types 也是一种 Entity Types
var isOwned = customerEntityType.IsOwned(); // true,OrderCustomerInfo 是 Owned Entity Types
var property = customerEntityType.GetProperty("OrderId")!;
Console.WriteLine(property.IsShadowProperty()); // true,"OrderId" 是 Shadow Property
Console.WriteLine(property.IsKey()); // true,"OrderId" 是 Primary Key
Console.WriteLine(property.IsForeignKey()); // true,"OrderId" 是 Foreign Key var orderEntityType = db.Model.FindEntityType(typeof(Order))!;
Console.WriteLine(orderEntityType.FindNavigation("CustomerInfo")!.ForeignKey); // "OrderId", CustomerInfo 属性不是普通的 Property 而是 Navigation
Two Table
默认情况下 Owned Entity Types (OrderCustomerInfo) 会和它的 Owner (Order) 共用一个 Table。
如果我们不希望这样,则可以使用 Entity Splitting 将它们分开成两个 Table。

column name prefix 会自动被拿掉。
效果


Sharing Owned Entity Types
Owned Entity Types 最好不要共用,不顺风水。
public class Address
{
public string Street1 { get; set; } = "";
public string Street2 { get; set; } = "";
public string PostalCode { get; set; } = "";
public string Country { get; set; } = "";
} public class Order
{
public int Id { get; set; }
public Address BillingAddress { get; set; } = null!;
public Address ShippingAddress { get; set; } = null!;
public decimal Amount { get; set; }
} public class Customer
{
public int Id { get; set; }
public string Name { get; set; } = "";
public Address Address { get; set; } = null!;
}
Order 和 Customer 都使用了 Address。
试想,如果是一对一关系,上面这样做成立吗?
答案是不成立,因为一对一关系是靠 id 作为 foreign key 维持关系的,上面这样就乱了套了。
我们测试看强制设置 Owned Entity Types 出来的效果是怎样的。
public class ApplicationDbContext() : DbContext()
{
public DbSet<Order> Orders => Set<Order>();
public DbSet<Customer> Customers => Set<Customer>(); protected override void OnModelCreating(ModelBuilder modelBuilder)
{
static void BuildAction<TEntity>(OwnedNavigationBuilder<TEntity, Address> builder) where TEntity : class
{
builder.Property(e => e.Street1).HasMaxLength(256);
builder.Property(e => e.Street2).HasMaxLength(256);
builder.Property(e => e.PostalCode).HasMaxLength(256);
builder.Property(e => e.Country).HasMaxLength(256);
} modelBuilder.Entity<Order>(
builder =>
{
builder.ToTable("Order");
builder.Property(e => e.Amount).HasPrecision(19, 2);
builder.OwnsOne(e => e.BillingAddress, BuildAction);
builder.OwnsOne(e => e.ShippingAddress, BuildAction);
}); modelBuilder.Entity<Customer>(
builder =>
{
builder.ToTable("Customer");
builder.Property(e => e.Name).HasMaxLength(256);
builder.OwnsOne(e => e.Address, BuildAction);
});
}
}
BuildAction 是共用的。
效果


如果做 Entity Splitting 的话,就会多出 3 个 Table -- CustomerAddress,OrderBillingAddress,OrderShippingAddress。
从这个结构可以看出,它底层依然是一对一的概念,只是在上层搞了许多映射。
我们进资料看看
using var db = new ApplicationDbContext();
var address = new Address
{
Street1 = "test",
Street2 = "test",
PostalCode = "81300",
Country = "Malaysia"
};
db.Orders.Add(new()
{
Amount = 100,
ShippingAddress = address,
BillingAddress = address
});
db.SaveChanges();
注意,shippingAddress 和 billingAddress 使用了同一个 address 对象。
运行结果是报错

因为官网声明了,Owned Entity Types 实例是不可以共享的,必须一个对一个。

我觉得 EF Core 如果硬硬要做映射是可以做到的,只是他们认为这种使用方式已经脱离了 Owned Entity Types 的本意,所以才不支持它。
但是,EF Core 8.0 推出的 Complex Types 支持这种使用方式,Complex Types 和 Owned Entity Types 有几分相似下一 part 会详细讲。
Collections of owned types
Owned Entity Types 不仅仅可以映射一对一关系,一对多关系也可以映射。
但是一对多就不可能共用同一个数据库 Table 了,一定是 2 个 Table。
其它特性,比如没有 DbSet,自动 Include,不能 share instance 这些则都一样。
来个简单的示范
Entity
public class Address
{
public string Street1 { get; set; } = "";
public string Street2 { get; set; } = "";
public string PostalCode { get; set; } = "";
public string Country { get; set; } = "";
} public class Customer
{
public int Id { get; set; }
public string Name { get; set; } = "";
public List<Address> Addresses { get; set; } = [];
}
ModelBuilder
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Customer>(
builder =>
{
builder.ToTable("Customer");
builder.Property(e => e.Name).HasMaxLength(256);
builder.OwnsMany(e => e.Addresses, builder =>
{
builder.Property(e => e.Street1).HasMaxLength(256);
builder.Property(e => e.Street2).HasMaxLength(256);
builder.Property(e => e.PostalCode).HasMaxLength(256);
builder.Property(e => e.Country).HasMaxLength(256);
});
});
}
数据库


和普通一对多的表结构是一样的。
using var db = new ApplicationDbContext();
var addressEntityType = db.Model.FindEntityType(typeof(Address))!;
addressEntityType.GetProperty("Id").IsKey(); // true
addressEntityType.GetProperty("Id").IsShadowProperty(); // true
addressEntityType.GetProperty("CustomerId").IsForeignKey(); // true
addressEntityType.GetProperty("CustomerId").IsShadowProperty(); // true
CustomerId 是 Foreign Key,Id 是 Primary Key,它们都是 Shadow Property。
如果想修改 Primary Key 和 Foreign Key 可以这样配置
builder.OwnsMany(e => e.Addresses, builder =>
{
builder.WithOwner().HasForeignKey("CustomerId2"); // rename foreign key CustomerId to CustomerId2
builder.Property<int>("Id").HasColumnName("AddressId"); // rename primary key Id to AddressId
});
How to detech Owned Entity Types modified?
相关 Issue:
Detecting if an owned entity was changed
Return true for IsModified on navigations pointing to Added or Deleted entities
How can I get a deleted owned entity from the parent entity?
我们来看一个简单的例子
public class Product
{
public int Id { get; set; }
public string Name { get; set; } = "";
public Address Address { get; set; } = null!;
} public class Address
{
public string Line1 { get; set; } = null!;
}
Address 是 Owned Entity Type。
var product = db.Products.AsTracking().Single();
product.Address.Line1 = "new line";
var isProductChanged = db.Entry(product).State == EntityState.Modified; // false
var isAddressPropertyModified = db.Entry(product).Reference(e => e.Address).IsModified; // false
var isAddressChanged = db.Entry(product.Address).State == EntityState.Modified; // true
var isLine1PropertyModified = db.Entry(product.Address).Property(e => e.Line1).IsModified; // true
我们从 product 对象进入到 address 对象里,然后修改 line1 的值。
可以看到,从 product entry 是完全感知不到任何 modified,只有 product.address entry 才能感知到 modified。
我们换一个修改方式
await using var db = new ApplicationDbContext(); var product = db.Products.AsTracking().Single();
var oldAddress = product.Address;
var newAddress = new Address { Line1 = "new line" };
product.Address = newAddress; var isProductChanged = db.Entry(product).State == EntityState.Modified; // false
var isAddressPropertyModified = db.Entry(product).Reference(e => e.Address).IsModified; // true
var isAddressChanged = db.Entry(product.Address).State == EntityState.Modified; // false
var isLine1PropertyModified = db.Entry(product.Address).Property(e => e.Line1).IsModified; // false
var isOldAddressDeleted = db.Entry(oldAddress).State == EntityState.Deleted; // true
var isNewAddressAdded = db.Entry(oldAddress).State == EntityState.Added; // true
新旧 address 对象替换,这样操作的话属于 add and delete,同时 product entry 的 address reference 会感知到 modified (注:但是 product entry 依旧是 unchanged 哦)。
To JSON
Owned Entity Types 还有一个强项,它可以以 JSON 格式保存到数据库里,不管是 OwnsOne 还是 OwnsMany 都行。
builder.OwnsMany(e => e.Addresses, builder =>
{
builder.ToJson();
builder.Property(e => e.Street1).HasMaxLength(256);
builder.Property(e => e.Street2).HasMaxLength(256);
builder.Property(e => e.PostalCode).HasMaxLength(256);
builder.Property(e => e.Country).HasMaxLength(256);
});
加一句 ToJson() 就可以了。
测试
using var db = new ApplicationDbContext();
db.Customers.Add(new()
{
Name = "Derrick",
Addresses = [
new() { Street1 = "test1", Street2 = "test1", PostalCode = "81300", Country = "Malaysia" },
new() { Street1 = "test2", Street2 = "test2", PostalCode = "123456", Country = "Singapore" }
]
});
db.SaveChanges();
效果

厉害吧
Nested Owned Entity Types
Owned Entity Types 支持嵌套,配置的方式和上面一样,在 OwnsOne / Many 里面继续调用 OwnsOne / Many 就可以了。
这里我就不演示了。
另外,ToJson 的话,一定要在最上层调用。
目前不支持一半一半的状况,要 JSON 就得从上层到下层通通 JSON。
Limitation

目前不支持 inheritance hierarchies 继承结构,TPH、TPT、TPC 通通不支持,希望未来会支持。
Complex Types
参考:Docs – Value objects using Complex Types
EF Core 8.0 推出了 Complex Types。Complex Types 和 Owned Entity Types 外观有点像,但内在思想是不同的。
Complex Types 在 Domain-driven design (领域驱动设计) 里被视作为 Value Object 的实现。很遗憾,我对 DDD 一窍不通,无法用 DDD 视角去解释它。
Current limitations
目前 Complex Types 还不算完整,它有很多该有得功能都还没有实现,要使用它要小心哦。

不支持一对多关系。
不支持 nullable
public OrderCustomerInfo? CustomerInfo { get; set; }像上面这样 OrderCustomerInfo 将无法设置成 Complex Types,因为它是 nullable。
不支持 ToJson。
这几个都挺需要的,既然都没有
和 Owned Entity Types 的共同点和区别
共同点:
没有 DbSet,不可以直接 Add 和 Query
- 自动 Include
区别:
Complex Types 不支持一对一映射到 two table。
Complex Types 不继承 Entity Types,因为它完全没有 Primary Key 概念。
Complex Types 的实例是可以共用的。
- Complex Types 更倾向使用 record 而非 class。
Config Complex Types
和 config Owned Entity Types 大同小异。
Entity
public class Order
{
public int Id { get; set; }
public OrderCustomerInfo CustomerInfo { get; set; } = null!;
public decimal Amount { get; set; }
} public class OrderCustomerInfo
{
public string Name { get; set; } = "";
public string Phone { get; set; } = "";
}
ModelBuilder
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Order>(
builder =>
{
builder.ToTable("Order");
builder.Property(e => e.Amount).HasPrecision(19, 2);
builder.ComplexProperty(e => e.CustomerInfo, builder =>
{
builder.Property(e => e.Name).HasMaxLength(256);
builder.Property(e => e.Phone).HasMaxLength(256);
});
});
}
效果

Entity Model
using var db = new ApplicationDbContext();
var customerInfoEntityType = db.Model.FindEntityType(typeof(OrderCustomerInfo)); // null
var orderEntityType = db.Model.FindEntityType(typeof(Order))!;
var customerInfoProperty = orderEntityType.FindProperty("CustomerInfo"); // null
var customerInfoComplexProperty = orderEntityType.FindComplexProperty("CustomerInfo");
OrderCustomerInfo 不是 Entity Types,所以 FindEntityType 是找不到的,这点和 Owned Entity Types 不同。
另外,CustomerInfo 也不是普通的 Property 也不是 Navigation,而是 ComplexProperty,要使用 FindComplexProperty 才能获取到,这点也和 Owned Entity Types 不同。
DbContext.Entry
Entity Model 不一样,那访问 Entry CurrentValue,IsModified 这些自然也不一样了。
Entity
public class Order
{
public int Id { get; set; }
public OrderCustomerInfo CustomerInfo { get; set; } = null!;
public Address ShippingAddress { get; set; } = null!;
public decimal Amount { get; set; }
}
假设 OrderCustomerInfo 是 Complex Types,ShippingAddress 是 Owned Entity Types
想访问 ShippingAddress 的 CurrentValue 通过 DbContext.Entry 就可以了。
var order = db.Orders.First();
var shippingAddressEntry = db.Entry(order.ShippingAddress);
var countryValue = shippingAddressEntry.Property(e => e.Country).CurrentValue;
想访问 CustomerInfo 的 CurrentValue 通过 DbContext.Entry 会报错。
var customerInfoEntry = db.Entry(order.CustomerInfo); // error
因为 Complex Types 不是 Entity Types,它没有 Key 的概念。
正确的方式是先进入 OrderEntry 然后使用 ComplexProperty 找到 CustomerInfo 在进入它的 Property 获取 CurrentValue
var orderEntry = db.Entry(order);
var nameValue = orderEntry.ComplexProperty(e => e.CustomerInfo).Property(e => e.Name).CurrentValue
Immutable
Value Object 虽然是对象,但它通常是值类型 (Immutable)。
所以一般都是使用 struct / record 而不是 class。(虽然 EF Core 支持使用 class 而且即使不是 Immutable 它也可以 tracking 到 changes)
Entity
public class Order
{
public int Id { get; set; }
public OrderCustomerInfo CustomerInfo { get; set; } = null!;
public decimal Amount { get; set; }
} public record OrderCustomerInfo(string Name, string Phone);
Add Order
using var db = new ApplicationDbContext();
db.Orders.Add(new()
{
Amount = 100,
CustomerInfo = new("Derrick", "+60 16-773 7062")
});
db.SaveChanges();
update CustomerInfo
var order = db.Orders.First();
order.CustomerInfo = order.CustomerInfo with { Name = "New Name" };
db.SaveChanges();
个人觉得使用 record 会比使用 class 更合适。不熟悉 record 的朋友可以看这篇 C# – Record, Class, Struct
总结
我们可以把 Owned Entity Types 视为变种的 one-to-one 和 one-to-many。
它最大的好处是自动 Include,自动 Table Splitting,而且可以 ToJson,底层思想继承自 one-to-one 和 one-to-many Entity Types 也算很好理解。
目前只有一个缺陷 -- 不支持继承结构。
Complex Types 不是 one-to-one 和 one-to-many 的概念,它没有 Key,它不是 Entity Types。
它适合用在 Object Value,就是说这些属性确确实实是 Property 只是它们有关系所以被 group 在一起。
比如说,地址本来是一个 string "11, Jalan Merak 22, Taman Mutiara Rini, 81300 Johor Malaysia",我想把它做的有结构,
于是拆分成 Street1, Street2, PostalCode, State, Country,这种情况就适合使用 Complex Types 来表达。
EF Core – Owned Entity Types & Complex Types的更多相关文章
- 【EF Core】Entity Framework Core 批处理语句
在Entity Framework Core (EF Core)有许多新的功能,最令人期待的功能之一就是批处理语句.那么批处理语句是什么呢?批处理语句意味着它不会为每个插入/更新/删除语句发送单独的请 ...
- Entity Framework (EF) Core工具创建一对多和多对多的关系
一. EntirtyFramework(EF)简介 EntirtyFramework框架是一个轻量级的可扩展版本的流行实体框架数据访问技术,微软官方提供的ORM工具让开发人员节省数据库访问的代码时间 ...
- 在EF Core里面如何使用以前EntityFramework的DbContext.Database.SqlQuery<SomeModel>自定义查询
问: With Entity Framework Core removing dbData.Database.SqlQuery<SomeModel> I can't find a solu ...
- ASP.NET Core 配置 Entity Framework Core - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core 配置 Entity Framework Core - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 配置 Entity Fram ...
- .NET 5/.NET Core使用EF Core 5连接MySQL数据库写入/读取数据示例教程
本文首发于<.NET 5/.NET Core使用EF Core 5(Entity Framework Core)连接MySQL数据库写入/读取数据示例教程> 前言 在.NET Core/. ...
- EF Core 新特性——Owned Entity Types
Owned Entity Types 首先owned entity type是EF Core 2.0的新特性. 至于什么是owned entity types,可以先把他理解为EF Core官方支持的 ...
- EFCore Owned Entity Types,彩蛋乎?鸡肋乎?之彩蛋篇
EFCore Owned Entity Types的定义 EFCore Owned Entity Types的文档在这里:https://docs.microsoft.com/zh-cn/ef/cor ...
- EFCore Owned Entity Types,彩蛋乎?鸡肋乎?之鸡肋篇
鸡肋 鸡肋(Chicken ribs),现代汉语词语,出自<三国志·魏书·武帝纪>裴松之注引<九州春秋>曰:"夫鸡肋,弃之如可惜,食之无所得,以比汉中,知王欲还也.& ...
- Lerning Entity Framework 6 ------ Complex types
Complex types are classes that map to a subset of columns of a table.They don't contains key. They a ...
- 张高兴的 Entity Framework Core 即学即用:(一)创建第一个 EF Core 应用
写在前面 Entity Framework Core (EF Core) 是 .NET 平台流行的对象关系映射(ORM)框架.虽然 .NET 平台中 ORM 框架有很多,比如 Dapper.NHibe ...
随机推荐
- C++使用gnuplot-cpp库绘制图像
最近想要对一些时变的变量进行可视化,搜索来搜索去选择了使用gnuplot这个工具. sudo apt-get install gnuplot sudo apt-get install gnuplot- ...
- [oeasy]python0132_变量含义_meaning_声明_declaration_赋值_assignment
变量定义 回忆上次内容 上次回顾了一下历史 python 是如何从无到有的 看到 Guido 长期的坚持和努力 编程语言的基础都是变量声明 python是如何声明变量的呢? 变量 想要定义变量 ...
- oeasy教您玩转vim - 37 - # 删除字符
通过十进制的 ascii 值输入字符 在输入模式下 输入 ctrl + v 然后再输入 065 通过十六进制的 unicode 在输入模式下 输入 ctrl + v 然后再输入 u2642 就可以 ...
- JS实现复制粘贴图片
最近在开发公司的可视化编辑器应用, 同事们提了一个需求, 即可以直接复制图片到编辑器中粘贴, 生成对应的图片组件. 因为传统的点击上传太麻烦, 得先把图片保存到本地, 然后再回到编辑器点击上传, 选择 ...
- Docker 容器数据:持久化
Docker 容器数据:持久化 每当从镜像创建容器时,它都会创建一个新容器,除了镜像数据之外没有任何数据 意味着如果在提交更改之前删除容器,我们将丢失数据 Docker 应该存在一种将数据的文件系统与 ...
- 对于同一个项目,同时将其git到GitHub和Gitee
对于同一个项目,你可以同时将其git到GitHub和Gitee.这通常通过配置多个远程仓库地址来实现.以下是一步步的操作指南: 一.在GitHub和Gitee上创建仓库 GitHub: 登录GitHu ...
- Spectre.Console.Cli注入服务的几种姿势
Spectre.Console大家可能都不陌生,写控制台程序美化还是不错的,支持着色,表格,图标等相当nice,如果对这个库不熟悉我强烈推荐你了解一下,对于写一些CLI小工具还是相当方便的, 本文主要 ...
- 【Vue】05 Webpack
Webpack是一个现代JS应用的静态模块打包的工具 学习Webpack需要我们安装NodeJS 配置CNPM & CRM 使用切换镜像的方式配置:[不建议] npm config set r ...
- Windows/Linux上更新Nessus插件
破解版:http://ximcx.cn/post-151.html 官网文档: https://docs.tenable.com/sccv/Content/OfflineNessusPluginUpd ...
- 强化学习算法:Learning to Learn: Meta-Critic Networks for Sample Efficient Learning
地址: https://arxiv.org/pdf/1706.09529 作者提出了一种叫做Meta-Critic的框架,该框架可以用于强化学习.监督学习等算法中.该算法在强化学习中可以实现元强化学习 ...