我目前正在讀一本書,但我卡在了特定章節的開頭。由于我被困的地方,可以在不違反付費墻的情況下在線找到背景關系。相關的代碼塊是這樣的:
public class NutshellContext : DbContext
{
public DbSet<Customer> Customers { get; set; }
public DbSet<Purchase> Purchases { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Customer>(entity =>
{
entity.ToTable("Customer");
entity.Property(e => e.Name).IsRequired(); // Column is not nullable
});
modelBuilder.Entity<Purchase>(entity =>
{
entity.ToTable("Purchase");
entity.Property(e => e.Date).IsRequired();
entity.Property(e => e.Description).IsRequired();
});
}
}
public class Customer
{
public int ID { get; set; }
public string Name { get; set; }
public virtual List<Purchase> Purchases { get; set; }
= new List<Purchase>();
}
public class Purchase
{
public int ID { get; set; }
public int? CustomerID { get; set; }
public DateTime Date { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public virtual Customer Customer { get; set; }
}
我糟糕的地方就在這里
modelBuilder.Entity<Customer>(entity =>
{
entity.ToTable("Customer");
entity.Property(e => e.Name).IsRequired(); // Column is not nullable
});
我的問題如下:
modelBuilder.Entity<Customer>似乎是一個函式呼叫。在函式呼叫中放置 lambda 運算式是什么意思?- 它是什么
entity以及為什么在范圍內?如果它只是一個自由變數,那么它在檔案中的哪個位置modelBuilder.Entity<T>說它可以將這樣的構造作為輸入? - 上面兩個問題,不過是針對
Property(e => e.Name)那段代碼。 - 如果
modelBuilder.Entity<Customer>不是函式呼叫,那么它是什么?
uj5u.com熱心網友回復:
方法 ( ) 的簽名modelBuilder.Entity<Customer>如下(來源:MSDN):
public virtual Microsoft.EntityFrameworkCore.ModelBuilder Entity<TEntity> (Action<Microsoft.EntityFrameworkCore.Metadata.Builders.EntityTypeBuilder<TEntity>> buildAction) where TEntity : class;
與我們相關的是爭論buildAction。它的型別是Action<EntityTypeBuilder<TEntity>>.
Action<T> 定義為 public delegate void Action<in T>(T obj);
這意味著 Action 只是一個函式,它接受型別 T 的引數并且不回傳任何內容。
使用lambda 運算式,我們可以創建匿名函式,因此entity => { ... }我們只是創建一個匿名函式,它接受一個我們決定命名的引數,entity它的范圍將是我們運算式的主體(所以里面是什么{...})。
引數的型別entity由編譯器推斷,因為它知道,如上所述,引數modelBuilder.Entity<Customer>是 Action< EntityTypeBuilder<TEntity> >。所以entity將是EntityTypeBuilder<TEntity>的一個實體,因此我們可以使用像這樣的方法ToTable
關于Property(e => e.Name)事情有點復雜......方法簽名如下(來源:MSDN):
public virtual Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder<TProperty> Property<TProperty> (System.Linq.Expressions.Expression<Func<TEntity,TProperty>> propertyExpression);
同樣,與我們相關的是論點propertyExpression。它的型別是Expression<Func<TEntity,TProperty>>.
這意味著它是一個運算式,它描述了一個函式(非常類似于上面描述的 Action,但不是什么都不回傳,而是回傳一個值),它接受一個e型別的引數(在我們的例子中我們任意命名)TEntity并回傳一個值的型別TProperty。
TEntity和都是TProperty編譯器推斷出來的:我們上面說entity的是 的實體EntityTypeBuilder<TEntity>,所以編譯器上面做出的推斷判斷TEntity現在仍然有效,因為我們呼叫的是 的實體方法entity。
TProperty是從 lambda 運算式 推斷出來的e => e.Name。這個運算式等同于e => { return e.Name; }.
基本上,這個 lambda 運算式是一個接受 的實體Customer并回傳其屬性的函式Name。在 Customer 類的定義中,我們將 Name 宣告為字串,以便編譯器知道它TProperty是string.
但請記住,我們傳遞給方法的引數Property( Property(e => e.Name)) 只是一個Expression,實際上并不是一個函式。基本上代碼e.Name永遠不會運行,因為它不是編譯函式。編譯器將生成一個運算式樹來描述我們實際撰寫的內容(請參閱運算式類的備注部分)。
然后物體框架將決議運算式以確定它需要在模型中映射的類的屬性。
uj5u.com熱心網友回復:
是modelBuilder.Entity<Customer>的是一個函式,它有這樣的簽名Entity<TEntity>(Action<EntityTypeBuilder<TEntity>>),所以基本上它接受其他“函式”(這里是一個委托動作)
從檔案:
此多載允許物體型別的配置在方法呼叫中在線完成,而不是在呼叫
Entity<TEntity>(). 這允許在物體型別的配置之后鏈接模型級別的其他配置。
所以它基本上是配置你已經通過的物體。
entity是引數的名稱,EntityTypeBuilder<TEntity>它不是free變數。此引數將在運行時由 EF 在您指定的 lambda 中傳遞
在這里與e => e.Name您一起選擇要更改的屬性
entity.Property(e => e.Name).IsRequired();
modelBuilder.Entity<Customer>這是一個函式呼叫
uj5u.com熱心網友回復:
它只是接受 Action 或 Function 作為委托的物體型別的多載方法/配置。
在早期版本的 EF 中,我們通過鏈接來實作:
modelBuilder.Entity<Customer>().ToTable("Customer").Property(e => e.Name).IsRequired();
這與
modelBuilder.Entity<Customer>(entity =>
{
entity.ToTable("Customer");
entity.Property(e => e.Name).IsRequired(); // Column is not nullable
});
但是正如檔案所說,這允許我們在模型級別添加額外的配置,以便在物體型別的配置之后鏈接。
但它通常做同樣的事情,它配置從 DBSet 屬性中公開的物體型別發現的模型:您的 Customer 物體駐留在資料庫中的 Customer 表中,并且屬性 Name 是必需的。
要進一步了解并回答您的#1 和#2 問題,請考慮以下問題:
Action<EntityTypeBuilder<Customer>> expression = (entity =>
{
entity.ToTable("Customer");
entity.Property(e => e.Name).IsRequired(); // Column is not nullable
});
modelBuilder.Entity<Customer>(expression);
物體方法需要一個委托,lambda 運算式僅用于創建一個 Action 委托。
uj5u.com熱心網友回復:
我不是 dotnet 中最先進的人,但從新手的角度來看,我會用一個簡單的短語回答你想要的:腳手架這是我朋友的一個例子
- 腳手架
當我們通過命令列使用腳手架時,EntityFramework 在您的背景關系檔案中生成這段代碼。
- 通過命令生成代碼后
這里的 modelBuilder.Entity是我在Context 檔案中宣告 AOC的 DBSet 。
現在物體代表我在本地 SQL 中創建的表,并希望在代碼中創建(先逆向工程資料庫,然后代碼)
Property(e => e.Opt)
Property意味著訪問你在你的表中的屬性
e => e.Opt:一個鏈接運算式它意味著
modelBuilder.Entity<Customer> 給定物體/表客戶的這個物體AOC(表)配置
modelBuilder.Entity<AOC>(entity =>
{
entity.ToTable("AOC");
entity.Property(e => e.Opt)
.HasMaxLength(2)
.IsUnicode(false);
});
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/537637.html
標籤:C#实体框架拉姆达
上一篇:決議https期間的Http失敗
