I'm currently reading a book and I'm stuck right at the start of a particularly chapter. Because of where I'm stuck, the context can be found online without breaching the paywall. The relevant codeblock is this:
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; }
}
The bit where I'm suck is here
modelBuilder.Entity<Customer>(entity =>
{
entity.ToTable("Customer");
entity.Property(e => e.Name).IsRequired(); // Column is not nullable
});
My questions are as follows:
modelBuilder.Entity<Customer>
appears to be a function call. What does it mean to place a lambda expression inside a function call?- What is
entity
and why is it in scope? If it is just a free variable, then where in the documentation formodelBuilder.Entity<T>
does it say that it can take such a construction as an input? - The above two questions, but for the
Property(e => e.Name)
piece of code. - If
modelBuilder.Entity<Customer>
isn't a function call, then what is it?
CodePudding user response:
Yes modelBuilder.Entity<Customer>
is a function it has such signature Entity<TEntity>(Action<EntityTypeBuilder<TEntity>>)
so basically it accepts other 'function' (here it's a delegate Action)
From documentation:
This overload allows configuration of the entity type to be done in line in the method call rather than being chained after a call to
Entity<TEntity>()
. This allows additional configuration at the model level to be chained after configuration for the entity type.
So it's basically configures entity you've passed.
entity
is the name of parameter EntityTypeBuilder<TEntity>
it's not a free
variable. This param will be passed inside the lambda you specified during run time by the EF
Here with e => e.Name
you are choosing which property you want change
entity.Property(e => e.Name).IsRequired();
modelBuilder.Entity<Customer>
It is a function call
CodePudding user response:
It's just an overload method/configuration of the entity type that accepts an Action or a Function as delegate.
In the earlier version of EF, we do this by chaining:
modelBuilder.Entity<Customer>().ToTable("Customer").Property(e => e.Name).IsRequired();
That's just the same with
modelBuilder.Entity<Customer>(entity =>
{
entity.ToTable("Customer");
entity.Property(e => e.Name).IsRequired(); // Column is not nullable
});
But as the documentation says, this allows us to add additional configuration at the model level to be chained after configuration for the entity type.
But it generally doing the same thing, it configures the model that was discovered from the entity types exposed in DBSet properties: that your Customer entity resides in Customer table from your database and the property Name is required.
To understand further and to answer your #1 and #2 questions, consider this:
Action<EntityTypeBuilder<Customer>> expression = (entity =>
{
entity.ToTable("Customer");
entity.Property(e => e.Name).IsRequired(); // Column is not nullable
});
modelBuilder.Entity<Customer>(expression);
Entity method is expecting a delegate, lambda expression is just used to create an Action delegate.