支援欄位
備份欄位允許 EF 讀取和/或寫入欄位,而不是屬性。 當類別中的封裝用於限制和/或透過應用程式程式代碼存取數據的語意時,這非常有用,但是值應該從 和/或寫入資料庫,而不使用這些限制/增強功能。
基本設定
依照慣例,下列欄位將會探索為指定屬性的備份欄位(以優先順序列出)。
<camel-cased property name>
_<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; }
}
}
請注意,備份欄位只會針對模型中包含的屬性進行探索。 如需模型中包含哪些屬性的詳細資訊,請參閱 包括和排除屬性。
您也可以使用 資料批註 或 Fluent 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;
}
}
欄位和屬性存取
根據預設,EF 一律會讀取和寫入備份欄位,假設已正確設定一個 ,而且永遠不會使用 屬性。 不過,EF 也支援其他存取模式。 例如,下列範例會指示 EF 只在具體化時寫入支援欄位,並在所有其他情況下使用 屬性:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(b => b.Url)
.HasField("_validatedUrl")
.UsePropertyAccessMode(PropertyAccessMode.PreferFieldDuringConstruction);
}
如需一組完整的支援選項,請參閱 PropertyAccessMode 列舉。
僅限欄位的屬性
您也可以在模型中建立概念屬性,該屬性在實體類別中沒有對應的CLR屬性,而是使用欄位來將數據儲存在實體中。 這與 陰影屬性不同,其中數據會儲存在變更追蹤器中,而不是儲存在實體的 CLR 類型中。 當實體類別使用方法而非屬性來取得/設定值時,通常會使用僅限欄位的屬性,或在領域模型中完全不應該公開字段的情況(例如主鍵)。
您可以在 API 中 Property(...)
提供名稱來設定只限欄位的屬性:
internal 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"));