简体   繁体   中英

Several DbContext for several projects. ASP.NET MVC EF

I'm going to move an old project to the ASP.NET MVC with EF and there is one issue.

My project includes several sub projects and every project have own tables, although the table structures are same.

Ex. XXX_Customers, YYY_Customers and etc.

I found one solution to realize what I want. (Use if-else-then statements).

Controller Action:

public ActionResult Index(string projectname)
    {
            List<Customers> list = new List<Customers>() ;

            if (projectname=="XXX")
            {
                list = new BaseContext().Customers.ToList();
            }
            else if (projectname=="YYY")
            {
                list = new BaseContext2().Customers.ToList();
            }
            return View(list);
    }

Models:

   public class Customers
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string UniqueValue { get; set; }
    }

   public class BaseContext : DbContext
    {
        public BaseContext()
            : base("myconnectionstring")
        {
            Configuration.LazyLoadingEnabled = false;
        }
        public DbSet<Customers> Customers { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Customers>().Property(p => p.Id).HasColumnName("ID");
            modelBuilder.Entity<Customers>().Property(p => p.Name).HasColumnName("Name");
            modelBuilder.Entity<Customers>().Property(p => p.UniqueValue).HasColumnName("UniqueValue");
            modelBuilder.Entity<Customers>().ToTable("XXX_Table1", "MyScheme");

        }
    }

    public class BaseContext2 : DbContext
    {
        public BaseContext2()
            : base("myconnectionstring")
        {
            Configuration.LazyLoadingEnabled = false;
        }
        public DbSet<Customers> Customers { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Customers>().Property(p => p.Id).HasColumnName("ID");
            modelBuilder.Entity<Customers>().Property(p => p.Name).HasColumnName("Name");
            modelBuilder.Entity<Customers>().Property(p => p.UniqueValue).HasColumnName("UniqueValue");
            modelBuilder.Entity<Customers>().ToTable("YYY_Table1", "MyScheme");

        }
    }

So, is there any good way to do this without if-else-then statement?

What you need is to implement the Factory Design Pattern .

  • Create an interface, call it IDBCustomers for example.
  • Make all relevant DbContext classes implement it.
  • Write a factory class that uses switch/case to return the correct implementation ( yes this is still like your if/then/else - but this way you do it once and don't scatter this kind of code in your entire codebase ).
  • Call GetDBCustomers on your factory and proceed as usual.

Read more on the net about the factory design pattern and why it's good for you.

Best of luck.

public interface IDbCustomer
{
    DbContext GetDbCustomer();
}

public class FactoryDbCustomer
{
    static public IDbCustomer GetDbContext(string projectName)
    {
        IDbCustomer obCustomer = null;

        switch (projectName)
        {
            case "XXX":
                obCustomer = new context1();
                break;
            case "YYY":
                obCustomer = new context2();
                break;
            default:
                break;
        }

        return obCustomer;
    }
}

public class context1 : IDbCustomer
{
    public DbContext GetDbCustomer()
    {
        return new BaseContext();
    }

}
public class context2 : IDbCustomer
{
    public DbContext GetDbCustomer()
    {
        return new BaseContext2();
    }

}

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