Reputation: 6809
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
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
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