EF class EntityTypeConfiguration is a very useful class, in nop to use this class to sub-sub-file configuration file mapping relationship Commerence in Model. Today I will talk about using the Repository pattern implementation example EntityTypeConfiguration in Entity Framework Code First in.
background
To simplify we will only use two tables: Classification Category, product type Product. The final project is structured as follows:
Note: EfRepPatTest.Entity and EfRepPatTest.Data class library project, EfRepPatTest.Implementation a console project. EfRepPatTest.Data project requires a reference to the Entity Framework class library.
BaseEntity.cs
BaseEntity create a base class for all entities, some common properties inside the package.
- public class BaseEntity<T>
- {
- public T Id { get; set; }
- }
This means that all entities have a field for the Id, the generic type which can meet all types of situations.
IRepository.cs:
The following defines a generic interface to the IRepository, including a generic add, delete, change.
- public interface IRepository<TEntity> where TEntity:class
- {
- IQueryable<TEntity> GetAll();
- TEntity GetById(object id);
- void Insert(TEntity entity);
- void Update(TEntity entity);
- void Delete(TEntity entity);
- }
Category.cs:
Entity classes classes
- public class Category:BaseEntity<int>
- {
- public virtual string Name { get; set; }
- public List<Product> Products { get; set; }
- }
Product.cs:
Physical products category
- public class Product:BaseEntity<long>
- {
- public virtual int CategoryId { get; set; }
- public virtual Category Category { get; set; }
- public virtual stringName{ get;set;}
- public virtual int MinimumStockLevel { get; set; }
- }
IDbContext.cs:
Some interfaces IDbContext EF package public interface method.
- public interface IDbContext
- {
- IDbSet<TEntity> Set<TEntity>() where TEntity:class;
- int SaveChanges();
- void Dispose ();
- }
DataContext.cs:
- public class DataContext: DbContext,IDbContext
- {
- public new IDbSet<TEntity> Set<TEntity>() where TEntity : class
- {
- return base.Set<TEntity>();
- }
- }
CategoryMap.cs:
Classification map class inherits EntityTypeConfigureation <T>
- public class CategoryMap:EntityTypeConfiguration<Category>
- {
- public CategoryMap()
- {
- ToTable("Category");
- HasKey(c => c.Id).Property(c => c.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
- Property(c => c.Name).IsRequired().HasMaxLength(50);
- }
- }
ProductMap.cs:
Product category mapping class inherits from EntityTypeConfigureation <T>
- public class ProductMap:EntityTypeConfiguration<Product>
- {
- public ProductMap()
- {
- ToTable("Product");
- HasKey(p => p.Id).Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
- //CategoryId as foreign key
- HasRequired(p => p.Category)
- .WithMany(c=>c.Products)
- .HasForeignKey(p => p.CategoryId);
- Property(p => p.Name).IsRequired().HasMaxLength(100);
- Property(p => p.MinimumStockLevel);
- }
- }
In DataContext class method override OnModelCreating order together with our new EF's Map configuration file, add the following code:
- modelBuilder.Configurations.Add(new CategoryMap());
- modelBuilder.Configurations.Add(new ProductMap());
- base.OnModelCreating(modelBuilder);
The optimization code can look above, may be utilized reflection automatically add the EF Map configuration file as follows:
- public class DataContext: DbContext,IDbContext
- {
- public new IDbSet<TEntity> Set<TEntity>() where TEntity : class
- {
- return base.Set<TEntity>();
- }
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()
- .Where(type => !String.IsNullOrEmpty(type.Namespace))
- .Where(type => type.BaseType != null && type.BaseType.IsGenericType &&
- type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
- foreach (var type in typesToRegister)
- {
- dynamicconfigurationInstance = Activator.CreateInstance(type);
- modelBuilder.Configurations.Add(configurationInstance);
- }
- base.OnModelCreating(modelBuilder);
- }
- }
The advantage is that after the new entity plus EF Map class, without modification DataContext.
RepositoryService.cs:
IRepositroy RepositoryService one particular implementation of the interface, the data access using the EF IDbContext.
- public class RepositoryService<TEntity>:IRepository<TEntity> where TEntity:class
- {
- private IDbContext Context;
- private IDbSet<TEntity> Entities
- {
- get { return this.Context.Set<TEntity>(); }
- }
- public RepositoryService(IDbContext context)
- {
- this.Context = context;
- }
- public IQueryable<TEntity> GetAll()
- {
- return Entities.AsQueryable();
- }
- public TEntity GetById(object id)
- {
- return Entities.Find(id);
- }
- public void Insert(TEntity entity)
- {
- Entities.Add(entity);
- }
- public void Update(TEntity entity)
- {
- if (entity == null)
- throw new ArgumentNullException("entity");
- this.Context.SaveChanges();
- }
- public void Delete(TEntity entity)
- {
- Entities.Remove(entity);
- }
- public void Dispose ()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- if (this.Context != null)
- {
- this.Context.Dispose();
- this.Context = null;
- }
- }
- }
- }
Create a new class DataBaseInitializer to initialize the class EF Code First database access.
- public class DataBaseInitializer : IDatabaseInitializer<DataContext>
- {
- public void InitializeDatabase(DataContext context)
- {
- context.Database.CreateIfNotExists();
- }
- }
Create a new console application to test the above code Program.cs:
- class Program
- {
- static void Main(string[] args)
- {
- var context = new DataContext();
- var dataBaseInitializer = new DataBaseInitializer();
- dataBaseInitializer.InitializeDatabase(context);
- var categoryRepository = new RepositoryService<Category>(context);
- //Adding category in the category entity
- var category = new Category ()
- {
- Name = "Baverage"
- };
- var products = new List<Product>();
- //Adding product in the product entity
- var product = new Product()
- {
- Name = "Soft Drink A",
- MinimumStockLevel = 50
- };
- products.Add(product);
- product = new Product()
- {
- Name = "Soft Drink B",
- MinimumStockLevel = 30
- };
- products.Add(product);
- category.Products = products;
- //Insert category and save changes
- categoryRepository.Insert(category);
- context.SaveChanges();
- ///////////////////////////////////////////////////////////////////////////////
- /////////////////For the next project we shall add Dependency Injection////////
- ////////////////But now we have add a Service layer for test manually//////////
- ///////////////////////////////////////////////////////////////////////////////
- IProductService productRepository = new ProductService();
- Console.WriteLine("\n");
- Console.WriteLine("Product List:");
- Console.WriteLine("-------------------------------------------------");
- foreach (var product1 in productRepository.GetAll())
- {
- Console.WriteLine(string.Format("Product Name : {0}",product1.Name));
- if (product1.Id == 9)
- {
- product1.Name = "Soft Drink AAA";
- productRepository.Update(product1);
- }
- }
- Console.WriteLine("Press any key to exit");
- Console.ReadKey();
- }
- }
Add a link to a database in the configuration file.
App.config:
- <?xml version="1.0" encoding="utf-8"?>
- <configuration>
- <configSections>
- <!-- For more information
- on Entity Framework configuration, visit
- http://go.microsoft.com/fwlink/?LinkID=237468 -->
- <section name="entityFramework"
- type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection,
- EntityFramework, Version=4.4.0.0, Culture=neutral,
- PublicKeyToken=b77a5c561934e089"
- requirePermission="false" />
- </configSections>
- <entityFramework>
- <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory,
- EntityFramework" />
- </entityFramework>
- <connectionStrings>
- <add name="DataContext"
- providerName="System.Data.SqlClient"
- connectionString="Data
- Source=YourSERVER;Initial Catalog=EfDBExistRepository;Integrated
- Security=True;MultipleActiveResultSets=True;"/>
- </connectionStrings>
- </configuration>
Note: The database link node named "DataContext", and just write our own class "DataContext" the same name. EF framework so you can automatically find this database link information.
Reference: http://www.codeproject.com/Articles/561584/Repository-Pattern-with-Entity-Framework-using