Home > front end >  Why is putting a lambda expression inside of a function call valid here?
Why is putting a lambda expression inside of a function call valid here?

Time:11-15

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:

  1. modelBuilder.Entity<Customer> appears to be a function call. What does it mean to place a lambda expression inside a function call?
  2. What is entity and why is it in scope? If it is just a free variable, then where in the documentation for modelBuilder.Entity<T> does it say that it can take such a construction as an input?
  3. The above two questions, but for the Property(e => e.Name) piece of code.
  4. 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.

  • Related