为什么ef core FisrtOrDefault()会调用实体参数构造函数?
why ef core FisrtOrDefault() will call the entity parameter constructor?
对不起,我的英语不是很好!!
我正在使用 ef core 3.1.4,我只是不明白
- 为什么【IQueryable.FirstOrDefault() 】方法会调用实体
参数构造函数?
- 映射规则是什么?
结果和代码在这里:
Program.cs 结果
Program.cs
using System;
using System.Linq;
using System.Text.Json;
using IdentityClient.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace IdentityClient
{
class Program
{
static void Main(string[] args) {
var services = new ServiceCollection();
services.AddDbContext<MyDbContext>(x => x.UseInMemoryDatabase("db"));
var provider = services.BuildServiceProvider();
var writeContext = provider.CreateScope().ServiceProvider.GetRequiredService<MyDbContext>();
var admin = new UserEntity("admin", "admin123");
Console.WriteLine(JsonSerializer.Serialize(admin));
writeContext.User.Add(admin);
writeContext.SaveChanges();
var readContext = provider.CreateScope().ServiceProvider.GetRequiredService<MyDbContext>();
var user = readContext.User.FirstOrDefault();
Console.WriteLine(user == null ? "" : JsonSerializer.Serialize(user));
Console.ReadLine();
}
}
}
MyDbContext.cs
using Microsoft.EntityFrameworkCore;
namespace IdentityClient.Data
{
public class MyDbContext:DbContext
{
public MyDbContext(DbContextOptions<MyDbContext> options):base(options)
{
}
public DbSet<UserEntity> User { get; set; }
}
}
UserEntity.cs
using System;
namespace IdentityClient.Data
{
public class UserEntity
{
//1.why query will call the constructor?
public UserEntity(string name, string password) {
Id=Guid.NewGuid();
Name = name;
Salt = Guid.NewGuid().ToString();
//2.why [Password] is different,what is the rule
Password = Salt;
}
public Guid Id { get; set; }
public string Name { get; set; }
public string Password { get; set; }
public string Salt { get; set; }
}
}
1.为什么查询会调用构造函数?
Starting with EF Core 2.1, it is now possible to define a constructor
with parameters and have EF Core call this constructor when creating
an instance of the entity. The constructor parameters can be bound to
mapped properties, or to various kinds of services to facilitate
behaviors like lazy-loading.
When EF Core creates instances of these types, such as for the results
of a query, it will first call the default parameterless constructor
and then set each property to the value from the database. However, if
EF Core finds a parameterized constructor with parameter names and
types that match those of mapped properties, then it will instead call
the parameterized constructor with values for those properties and
will not set each property explicitly.
https://docs.microsoft.com/en-us/ef/core/modeling/constructors
2。为什么[密码]不同,规则是什么?
根据 Microsoft 文档,您可以按照以下约定将查询结果映射到实体属性:
The parameter types and names must match property types and names,
except that properties can be Pascal-cased while the parameters are
camel-cased.
如果您不接受特定 属性 的参数,它将隐式映射。所以盐从查询中填充,密码从构造函数中填充。
后记:在构造函数中被另一个属性设置属性不是一个好习惯。因为声明或声明的顺序可能会影响最终结果。例如,在您的情况下,当您在 this example 中相互更改第 19,20 行时,您将获得预期的结果,并且代码中的气味很糟糕。
对不起,我的英语不是很好!!
我正在使用 ef core 3.1.4,我只是不明白
- 为什么【IQueryable.FirstOrDefault() 】方法会调用实体 参数构造函数?
- 映射规则是什么?
结果和代码在这里:
Program.cs 结果
Program.cs
using System;
using System.Linq;
using System.Text.Json;
using IdentityClient.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace IdentityClient
{
class Program
{
static void Main(string[] args) {
var services = new ServiceCollection();
services.AddDbContext<MyDbContext>(x => x.UseInMemoryDatabase("db"));
var provider = services.BuildServiceProvider();
var writeContext = provider.CreateScope().ServiceProvider.GetRequiredService<MyDbContext>();
var admin = new UserEntity("admin", "admin123");
Console.WriteLine(JsonSerializer.Serialize(admin));
writeContext.User.Add(admin);
writeContext.SaveChanges();
var readContext = provider.CreateScope().ServiceProvider.GetRequiredService<MyDbContext>();
var user = readContext.User.FirstOrDefault();
Console.WriteLine(user == null ? "" : JsonSerializer.Serialize(user));
Console.ReadLine();
}
}
}
MyDbContext.cs
using Microsoft.EntityFrameworkCore;
namespace IdentityClient.Data
{
public class MyDbContext:DbContext
{
public MyDbContext(DbContextOptions<MyDbContext> options):base(options)
{
}
public DbSet<UserEntity> User { get; set; }
}
}
UserEntity.cs
using System;
namespace IdentityClient.Data
{
public class UserEntity
{
//1.why query will call the constructor?
public UserEntity(string name, string password) {
Id=Guid.NewGuid();
Name = name;
Salt = Guid.NewGuid().ToString();
//2.why [Password] is different,what is the rule
Password = Salt;
}
public Guid Id { get; set; }
public string Name { get; set; }
public string Password { get; set; }
public string Salt { get; set; }
}
}
1.为什么查询会调用构造函数?
Starting with EF Core 2.1, it is now possible to define a constructor with parameters and have EF Core call this constructor when creating an instance of the entity. The constructor parameters can be bound to mapped properties, or to various kinds of services to facilitate behaviors like lazy-loading.
When EF Core creates instances of these types, such as for the results of a query, it will first call the default parameterless constructor and then set each property to the value from the database. However, if EF Core finds a parameterized constructor with parameter names and types that match those of mapped properties, then it will instead call the parameterized constructor with values for those properties and will not set each property explicitly.
https://docs.microsoft.com/en-us/ef/core/modeling/constructors
2。为什么[密码]不同,规则是什么?
根据 Microsoft 文档,您可以按照以下约定将查询结果映射到实体属性:
The parameter types and names must match property types and names, except that properties can be Pascal-cased while the parameters are camel-cased.
如果您不接受特定 属性 的参数,它将隐式映射。所以盐从查询中填充,密码从构造函数中填充。
后记:在构造函数中被另一个属性设置属性不是一个好习惯。因为声明或声明的顺序可能会影响最终结果。例如,在您的情况下,当您在 this example 中相互更改第 19,20 行时,您将获得预期的结果,并且代码中的气味很糟糕。