简体   繁体   中英

Functional grouping in DbContext for EF6 using FluentAPI and Code First

I have a complex object model that I'm trying to tightly control using FluentAPI. I'm ending up with large blocks of code that look like this:

        modelBuilder.Entity<Product>().Property(t => t.Category).IsRequired();
        modelBuilder.Entity<Product>().Property(t => t.Description).IsOptional();
        modelBuilder.Entity<Product>().Property(t => t.Name).IsRequired();
        modelBuilder.Entity<Product>().Property(t => t.PricingAnalyst).IsOptional();
        modelBuilder.Entity<Product>().Property(t => t.ProductCode).IsRequired();
        modelBuilder.Entity<Product>().Property(t => t.ReplacedByProductCode).IsOptional();
        modelBuilder.Entity<Product>().Property(t => t.Section).IsOptional();
        modelBuilder.Entity<Product>().HasMany<ProductReference>(s => s.References);
        modelBuilder.Entity<Product>().HasMany<ProductWeight>(s => s.Weights);
        modelBuilder.Entity<Product>().HasMany<ProductDate>(s => s.Dates);
        modelBuilder.Entity<Product>().HasMany<ProductNote>(s => s.Notes);
        modelBuilder.Entity<Product>().HasMany<Rule>(s => s.Rules);
        modelBuilder.Entity<Product>().HasOptional<PriceDetail>(s => s.Pricing);
        modelBuilder.Entity<Product>().HasOptional<ProductCosting>(s => s.Costing);
        modelBuilder.Entity<Product>().HasMany<Update>(u => u.Updates);

It seemed to me like I could stop typing modelBuilder.Entity<Product>() so much if I could do something to the effect of

using (modelBuilder.Entity<Product>() p)
{
    p.Property(t => t.PricingAnalyst).IsOptional();
    ...
    p.HasMany<ProductReference>(s => s.References);
}

would save me a lot of effort, but I can't work out how to structure the using statement correctly. Is this the right road? If not, what do I do to shorthand the code and make it more readable?

Update:

Based on the provided answer, I've created blocks in my :DbContext file that look similar to this:

        {
            var rule = modelBuilder.Entity<Rule>();
            rule.HasKey(r => r.ID);
            rule.Property(r => r.Country).IsRequired();
            rule.Property(r => r.Description).IsOptional();
            rule.Property(r => r.ReviewDate).IsOptional();
            rule.Property(r => r.RuleNumber).IsRequired();
            rule.HasMany<Update>(r => r.Updates);
            rule.HasMany<Condition>(r => r.Conditions);
        }

I chose to wrap each block in curly braces to contain the scope of the var so I didn't have some copy/paste accident elsewhere in the code. I like the way this works, and it makes my code readable (at least to me, hopefully by others).

Sounds like you just want:

using (var p = modelBuilder.Entity<Product>())
{
    //...
}

However, this will only work if the result of modelBuilder.Entity<Product>() implements IDisposable . Going through the MSDN info on the subject, it looks like it doesn't. If not, you can probably do fine with:

var p = modelBuilder.Entity<Product>();
//...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM