支持字段Backing Fields
支持字段允许 EF 读取和/或写入字段,而不是属性。 当使用类中的封装来限制和/或通过应用程序代码对数据访问进行限制时,这可能很有用,但在不使用这些限制/增强功能的情况下,应从数据库中读取和/或写入值。
基本配置Basic configuration
按照约定,将发现以下字段作为给定属性的支持字段(按优先级顺序列出)。
_<camel-cased property name>
_<property name>
m_<camel-cased property name>
m_<property name>
在下面的示例中, Url
将属性配置为具有_url
其支持字段:
public class Blog
{
private string _url;
public int BlogId { get; set; }
public string Url
{
get { return _url; }
set { _url = value; }
}
}
请注意,仅为模型中包含的属性发现支持字段。 有关模型中包含哪些属性的详细信息,请参阅包括 & 排除属性。
你还可以使用数据批注(在 EFCore 5.0 中提供)或流畅的 API (例如,如果该字段名称与上述约定不对应)来配置支持字段:
public class Blog
{
private string _validatedUrl;
public int BlogId { get; set; }
[BackingField(nameof(_validatedUrl))]
public string Url
{
get { return _validatedUrl; }
}
public void SetUrl(string url)
{
// put your validation code here
_validatedUrl = url;
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(b => b.Url)
.HasField("_validatedUrl");
}
字段和属性访问Field and property access
默认情况下,EF 将始终读取并写入到支持字段-假设已正确配置了一个字段,并且永远不会使用属性。 但是,EF 还支持其他访问模式。 例如,下面的示例指示 EF 仅在具体化时写入支持字段,并在所有其他情况下使用属性:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(b => b.Url)
.HasField("_validatedUrl")
.UsePropertyAccessMode(PropertyAccessMode.PreferFieldDuringConstruction);
}
有关完整的支持选项集,请参阅PropertyAccessMode 枚举。
备注
使用 EF Core 3.0,默认属性访问模式从PreferFieldDuringConstruction
更改为。 PreferField
仅限字段的属性Field-only properties
您还可以在您的模型中创建一个概念属性,该属性在实体类中不具有相应的 CLR 属性,而是使用字段来存储实体中的数据。 这不同于阴影属性,其中的数据存储在更改跟踪器中,而不是存储在实体的 CLR 类型中。 仅字段属性在实体类使用方法而不是属性来获取/设置值时使用,或者在字段不应在域模型中公开(例如主键)的情况下使用。
可以通过在Property(...)
API 中提供名称来配置仅限字段的属性:
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;
}
}
EF 将尝试查找具有给定名称的 CLR 属性,如果找不到属性,则尝试查找一个字段。 如果属性和字段均未找到,则将改为设置影子属性。
您可能需要从 LINQ 查询中引用仅限字段的属性,但此类字段通常是私有的。 可以在 LINQ 查询EF.Property(...)
中使用方法来引用字段:
var blogs = db.blogs.OrderBy(b => EF.Property<string>(b, "_validatedUrl"));