NevenHuynh
NevenHuynh

Reputation: 6809

EF 4.1 using code first do not create new database

I create a new web using Entity framework 4.1 code first approach with seperate layers :

In Model layer, i define class models

In Data layer, i define repository class

In Database layer, i implement repository class. Create context , i implemented DbContext to custom my own table.

Finally, i add reference of the layers to the website (presentation layer). After i run my website, EF 4.1 do not create database in App_Data folder. I wonder which steps that i do wrong. please have a look into my code and give me some suggestion. Thanks in advance !

I just add code of classes i consider that contain error in them. Other class models in Model layer and class repositories in Data layer are not related to the error. So i do not write them here.

web.config:

<add name="ApplicationServices" connectionString="Data Source=DESKTOP\Neven;Initial Catalog=aspnetdb;Integrated Security=True" providerName="System.Data.SqlClient" />
      <add name="FashionShopData" connectionString="Data Source=|DataDirectory|FashionShopData.mdf;Initial Catalog=FashionShopData;Integrated Security=True" providerName="System.Data.SqlClient" />

In Global.asax :

    protected void Application_Start()
        {

            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);

            ModelMetadataProviders.Current = new MetadataProvider();
            InitialDatabase();
        }

private static void InitialDatabase()
        {
            var repositoryInitializer = new RepositoryInitializer();
            repositoryInitializer.Initialize();
        }

In Database SQL Layer :

the context

    using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using FashionShop.Data.Repositories;
using FashionShop.Models;

namespace FashipShop.Data.Sql
{

    public partial class FashionShopContext : DbContext, IUnitOfWork
    {
        /// <summary>
        /// This method sets up the database appropriately for the available model objects.
        /// This method only sets up the data tier.  
        /// Any shared or model level requirements (data validations, etc) are on the model objects themselves.
        /// </summary>
        /// <param name="modelBuilder">The model builder object for creating the data model.</param>
        public FashionShopContext()
        : base("name=FashionShopData")
    {

    }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {

            SetupUserEntity(modelBuilder);

            SetupCategoryEntity(modelBuilder);

            SetupProductEntity(modelBuilder);

            SetupOrderEntity(modelBuilder);

        }

        private static void SetupUserEntity(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<User>().HasKey(r => r.UserId);
            modelBuilder.Entity<User>().Property(r => r.UserId).HasDatabaseGeneratedOption(
                DatabaseGeneratedOption.Identity);

            modelBuilder.Entity<User>().HasMany(o => o.Orders);

            modelBuilder.Entity<User>().Property(r => r.Email).IsRequired();
        }

        private static void SetupCategoryEntity(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Category>().HasKey(c => c.CateId);
            modelBuilder.Entity<Category>().Property(c => c.CateId).HasDatabaseGeneratedOption(
                DatabaseGeneratedOption.Identity);
            modelBuilder.Entity<Category>().Property(c => c.ParentId).IsOptional();
            modelBuilder.Entity<Category>().HasMany(p => p.Products);
        }

        private static void SetupProductEntity(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Product>().HasKey(p => p.ProductId);
            modelBuilder.Entity<Product>().Property(p => p.ProductId).HasDatabaseGeneratedOption(
                DatabaseGeneratedOption.Identity);

            modelBuilder.Entity<Product>().HasRequired(c => c.Category).WithRequiredPrincipal().WillCascadeOnDelete(true);
        }

        private static void SetupOrderEntity(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Order>().HasKey(o => o.OrderId);
            modelBuilder.Entity<Order>().Property(o => o.OrderId).HasDatabaseGeneratedOption(
                DatabaseGeneratedOption.Identity);
            modelBuilder.Entity<Order>().HasMany(p => p.Products).WithMany(o => o.Orders).Map(op =>
                                                                                                  {
                                                                                                      op.ToTable(
                                                                                                          "ProductOrder");
                                                                                                      op.MapLeftKey(
                                                                                                          "OrderId");
                                                                                                      op.MapRightKey(
                                                                                                          "ProductId");
                                                                                                  });
        }

        public DbSet<User> Users { get; set; }

        public DbSet<Category> Categories { get; set; }

        public DbSet<Product> Products { get; set; }

        public DbSet<Order> ShoppingCarts { get; set; }

        void IUnitOfWork.SaveChanges()
        {
            base.SaveChanges();
        }
    }
}

The repository initialize code :

    using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using FashionShop.Data.Repositories;

namespace FashipShop.Data.Sql
{
    public class RepositoryInitializer : IRepositoryInitializer
    {

        public RepositoryInitializer()
        {
            Database.DefaultConnectionFactory = new SqlConnectionFactory();
        }

        public void Initialize()
        {
            Database.SetInitializer(new CreateDatabaseIfNotExists<FashionShopContext>());
        }
    }
}

Generic Repository :

    using System;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using FashionShop.Data.Repositories;


namespace FashipShop.Data.Sql.Repositories
{    
    public abstract class GenericRepository<T>: IGenericRepository<T> where T:class {
        protected IUnitOfWork UnitOfWork { get; set; }
        protected FashionShopContext Context { get { return (FashionShopContext)this.UnitOfWork; } }

        public GenericRepository(IUnitOfWork unitOfWork)
        {
            if (unitOfWork == null) throw new ArgumentNullException("unitOfWork");
            this.UnitOfWork = unitOfWork;
        }

        public virtual IQueryable<T> GetAll()
        {
            IQueryable<T> query  = Context.Set<T>();
            return query;
        }

        public IQueryable<T> FindBy(Expression<Func<T, bool>> predicate)
        {
            IQueryable<T> query = Context.Set<T>().Where(predicate);
            return query;
        }

        public virtual void Add(T entity)
        {
            Context.Set<T>().Add(entity);
            Context.SaveChanges();
        }

        public virtual void Delete(T entity)
        {
            Context.Set<T>().Remove(entity);
            Context.SaveChanges();
        }

        public virtual void Edit(T entity)
        {
            Context.Entry(entity).State = EntityState.Modified;
            Context.SaveChanges();
        }
    }



}

i have found the mistake, because i never using code in my presentation layer so EF do not initialize the database, i need to add

FashionShopContext context = new FashionShopContext(); 
context.Database.Initialize(true);

into Application_Start(). But after i changed code and there is another error :

"A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server"

here is the connection string that i used :

<add name="FashionShopData" connectionString="Data Source=|DataDirectory|FashionShopData.mdf;Initial Catalog=FashionShopData;Integrated Security=True" providerName="System.Data.SqlClient" />

Is my connection string is wrong ? how do i correct it ?

Upvotes: 1

Views: 1779

Answers (2)

Sampath
Sampath

Reputation: 65870

Your problem is initiating of the connection string, which you set on DbContext derived class.

It should be like below.

public partial class FashionShopContext : DbContext, IUnitOfWork
{

   public static string ConnectionString { get; set; }

   public FashionShopContext() : base(ConnectionString ?? "FashionShopData")
    {

    }
}

Global.asax

protected void Application_Start()
{
FashionShopContext.ConnectionString = ConfigurationManager.ConnectionStrings["FashionShopData"].ConnectionString;
}

I hope this will help to you.

Upvotes: 0

phil soady
phil soady

Reputation: 11328

try..

<add name="ContextName" connectionString="Data Source=ServerName;Initial Catalog=DBCataloName;Integrated Security=True;MultipleActiveResultSets=True;App=EntityFramework"
   providerName="System.Data.SqlClient" />

Upvotes: 1

Related Questions