Entity Framework 5 da Generic Repository Pattern
Entity Framework 5 da Generic Repository Patterndan foydalanish
Generic haqida tushuncha:
.Net 2.0 dan boshlab Genericlardan foydalanish imkoniyati qo’shildi. Generic yordamida ixtiyoriy tipda ishlovchi(ixtiyoriy tipga moslashuvchi) metod yoki class yaratish mumkin. Bunda class yoki metod tipi uchun maxsus shablon belgisi — «T» dan foydalaniladi. Kompilyator har bir tipga mos shu tipdagi metod yoki classni generatsiya qiladi. Generic dan foydalanish uchun “using” bo’limiga using System.Collections.Generic; ni qo’shish lozim.
Masalan:
1)
Dasturni ishga tushirgach quyidagi natijani olishimiz mumkin:
Generic metodlar:
Generic yordamida universal tip parametriga ega bo’lgan metod yaratishimiz mumkin
Masalan:
2)
Natija:
Generic Repository Pattern:
1) Yangi Consule Application yaratamiz va unda “Models” deb nomlangan papka hosil qilamiz. Uning ichiga Person.cs nomli classni qo’shamiz.
Pesron.cs:
2) Proyekt ichida “Repository” papkasini hosil qilamiz va unga “IMyRepository” interfeysini va “MyRepository” classini qo’shamiz.
IMyRepository.cs:
MyRepository.cs:
Modelga mos jadvallani hosil qilish uchun qo’shimcha Configuration.cs classini hozil qilamiz. Buning uchun proyektga “Migrations” nomli papka qo’shamiz.
Configuration.cs:
“app.config” faylida Dbga bog’lanish uchun kerak bo’ladigan connectionString ni aniqlab qo’yamiz:
app.config:
Proyektda DB deb nomlangan papka hosil qilamiz va uning ichiga DbConfig.cs va DBContext.cs classlarini qo’shamiz:
DbConfig.cs:
DBContext.cs:
Endi yaratilgan Repositorydan foydalanib bazada model bo’yicha jadvalni hosil qilish va unda CRUD(Create, Read, Update, Delete) amallarini bajarishimiz mumkin:
Program.cs:
Natija:
Generic haqida tushuncha:
.Net 2.0 dan boshlab Genericlardan foydalanish imkoniyati qo’shildi. Generic yordamida ixtiyoriy tipda ishlovchi(ixtiyoriy tipga moslashuvchi) metod yoki class yaratish mumkin. Bunda class yoki metod tipi uchun maxsus shablon belgisi — «T» dan foydalaniladi. Kompilyator har bir tipga mos shu tipdagi metod yoki classni generatsiya qiladi. Generic dan foydalanish uchun “using” bo’limiga using System.Collections.Generic; ni qo’shish lozim.
Masalan:
1)
using System;
using System.Collections.Generic;
namespace GenericApplication
{
public class MyGenericArray<T>
{
private T[] array;
public MyGenericArray(int size)
{
array = new T[size + 1];
}
public T getItem(int index)
{
return array[index];
}
public void setItem(int index, T value)
{
array[index] = value;
}
}
class Tester
{
static void Main(string[] args)
{
//Butun tipdagi massivni e’lon qilish:
MyGenericArray<int> intArray = new MyGenericArray<int>(5);
//Massiv elementlariga qiymat berish:
for (int c = 0; c < 5; c++)
{
intArray.setItem(c, c*5);
}
//Massiv elementlarini chop qilish
Console.Write("Butun tipli massiv elementlari:");
for (int p = 0; p < 5; p++)
{
Console.Write(intArray.getItem(p) + " ");
}
Console.WriteLine();
//Belgi tipidagi massivni hosil qilish:
String myName=”Mansur”;
MyGenericArray<char> charArray = new MyGenericArray<char>(5);
for (int c = 0; c < myName.Length; c++)
{
charArray.setItem(c, myName[c]);
}
Console.Write("Belgi tipidagi massiv elementlari:");
for (int p = 0; p< myName.Length; p++)
{
Console.Write(charArray.getItem(p) + " ");
}
Console.WriteLine();
Console.ReadKey();
}
}
}
Dasturni ishga tushirgach quyidagi natijani olishimiz mumkin:
0 5 10 15 20
M a n s u r
Generic metodlar:
Generic yordamida universal tip parametriga ega bo’lgan metod yaratishimiz mumkin
Masalan:
2)
using System;
using System.Collections.Generic;
namespace GenericTest1
{
class Program
{
private static void swap<K>(ref K p1,ref K p2)
{
Console.WriteLine("p1={0}, p2={1}",p1,p2);
K temp = p1;
p1 = p2;
p2 = temp;
Console.WriteLine("p1={0}, p2={1}", p1, p2);
Console.WriteLine("----------------------");
}
static void Main(string[] args)
{
int a = 10, b = 25;
swap(ref a, ref b);
string firstName = "Mansur", lastName = "Kurtov";
swap(ref firstName, ref lastName);
Console.ReadLine();
}
}
}
Natija:
Generic Repository Pattern:
1) Yangi Consule Application yaratamiz va unda “Models” deb nomlangan papka hosil qilamiz. Uning ichiga Person.cs nomli classni qo’shamiz.
Pesron.cs:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace EntityCrudApp2.Model
{
[Table("Pesons", Schema = "dbo")] //Bazadagi jadval nomi – “Persons”
public class Person
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] //Primery key
public int Id { get; set; }
[Required]
[StringLength(250)] //'Not nul'(bo'sh qiymat qabul qilmaydi) va uzunligi 250 bo’lgan belgi
public string Name { get; set; }
}
}
2) Proyekt ichida “Repository” papkasini hosil qilamiz va unga “IMyRepository” interfeysini va “MyRepository” classini qo’shamiz.
IMyRepository.cs:
using System;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
namespace EntityCrudApp2.Repository
{
public interface IMyRepository<T> : IDisposable where T : class
{
DbContext Context { get; }
IQueryable<T> All();
IQueryable<T> Filter(Expression<Func<T, bool>> predicate);
bool Contains(Expression<Func<T, bool>> predicate);
T Find(params object[] keys);
T Find(Expression<Func<T, bool>> expression);
T Create(T t);
int Delete(T t);
int Delete(Expression<Func<T, bool>> predicate);
int Update(T t);
void Execute(string command, params object[] parameters);
void SaveChanges();
}
}
MyRepository.cs:
using System;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using EntityCrudApp2.DB;
namespace EntityCrudApp2.Repository
{
public class MyRepository<T> : IMyRepository<T> where T : class
{
public DbContext Context { get; private set; }
public MyRepository()
: this(new DbContext())
{
String s;
int k=s.Length
}
public MyRepository(DbContext context)
{
Context = context;
}
public IQueryable<T> All()
{
return Filter(null);
}
public IQueryable<T> Filter(Expression<Func<T, bool>> predicate)
{
var query = Context.Set<T>();
return predicate!=null ? query.Where(predicate) : query;
}
public bool Contains(Expression<Func<T, bool>> predicate)
{
return Find(predicate) != null;
}
public T Find(params object[] keys)
{
return Context.Set<T>().Find(keys);
}
public T Find(Expression<Func<T, bool>> expression)
{
return Context.Set<T>().FirstOrDefault(expression);
}
public T Create(T t)
{
Context.Entry(t).State = EntityState.Added;
Context.Set<T>().Add(t);
SaveChanges();
return t;
}
public int Delete(T t)
{
Context.Entry(t).State = EntityState.Deleted;
Context.Set<T>().Remove(t);
SaveChanges();
return 0;
}
public int Delete(Expression<Func<T, bool>> predicate)
{
var t = Find(predicate);
Context.Entry(t).State = EntityState.Deleted;
Context.Set<T>().Remove(t);
SaveChanges();
return 0;
}
public int Update(T t)
{
Context.Entry(t).State=EntityState.Modified;
Context.Set<T>().Attach(t);
SaveChanges();
return 0;
}
public void Execute(string command, params object[] parameters)
{
Context.Database.ExecuteSqlCommand(command, parameters);
// Stored proceduralarni ishga tushirish uchun ishlatiladi
SaveChanges();
}
public void SaveChanges()
{
Context.SaveChanges();
}
public void Dispose()
{
Context.Dispose();
}
}
}
Modelga mos jadvallani hosil qilish uchun qo’shimcha Configuration.cs classini hozil qilamiz. Buning uchun proyektga “Migrations” nomli papka qo’shamiz.
Configuration.cs:
namespace EntityCrudApp2.Migrations
{
using System.Data.Entity.Migrations;
internal sealed class Configuration : DbMigrationsConfiguration<EntityCrudApp2.DB.DbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
}
}
“app.config” faylida Dbga bog’lanish uchun kerak bo’ladigan connectionString ni aniqlab qo’yamiz:
app.config:
…
<connectionStrings>
<add name="myConnectionString"
connectionString="Data Source=.;Initial Catalog=MansurDB1;User Id=sa;password=mansur;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.EntityClient" />
</connectionStrings>
…
Proyektda DB deb nomlangan papka hosil qilamiz va uning ichiga DbConfig.cs va DBContext.cs classlarini qo’shamiz:
DbConfig.cs:
using System.Data.Entity;
namespace EntityCrudApp2.DB
{
public static class DbConfig
{
public static void Configure()
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<DbContext, Migrations.Configuration>());
}
}
}
DBContext.cs:
using System.Configuration;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using EntityCrudApp2.Model;
namespace EntityCrudApp2.DB
{
public class DBContext : DbContext
{
private static readonly string ConnectionString;
static DBContext()
{
ConnectionString = ConfigurationManager.ConnectionStrings["myConnectionString "].ConnectionString;
}
public DbContext()
: base(ConnectionString)
{
}
public DbSet<Person> Persons { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
}
Endi yaratilgan Repositorydan foydalanib bazada model bo’yicha jadvalni hosil qilish va unda CRUD(Create, Read, Update, Delete) amallarini bajarishimiz mumkin:
Program.cs:
using System;
using EntityCrudApp2.DB;
using EntityCrudApp2.Model;
using EntityCrudApp2.Repository;
namespace EntityCrudApp2
{
class Program
{
static void Main(string[] args)
{
DbConfig.Configure();
using (IMyRepository<Person> repository = new MyRepository<Person>())
{
repository.Create(new Person
{
Name = "Programmer 1"
});
Console.WriteLine("Bazaga qo'shilgan 'Person'lar ro'yxati:");
foreach (var person in repository.All())
{
Console.WriteLine(person.Name);
}
}
Console.ReadLine();
}
}
}
Natija:
Bazaga qo'shilgan 'Person'lar ro'yxati:
Programmer 1
Bitta savolim bor:
Shu yerda repository.All() da Allni o'rniga boshqa so'rov yozib hamma Personlarni emas, ba'zilarini olib chiqish kerak bo'lsa, Entity framwork bazadan hamma Personlarni olib vhiqib keyin bizi so'rovimizga filterlab beradimi yoki bazaga filterlangan SQl so'rov jo'natadimi?