AUTHOR: Hristo Merdjanov
DATE POSTED: October 30, 2015
Entity Framework`s Database First approach provides very little control over the models used in the application. It automatically generates a lot of files which should not be altered and at times versioning of the database becomes very difficult.
The Code First approach, on the other hand, delivers exactly the opposite. That is why, especially in recent times and for new projects, the developer community chooses this way to interact with SQL Server. Another great advantage is that the database can be entirely managed by the application. Changes in the models are also automatically reflected by the ORM engine at the end migrated to the database itself.
We are going to take this example project even further by implementing Repository Pattern and Unit of Work. Our implementation consists of three projects each defining a separate layer of the application.
Our RadGridView control will be setup in hierarchy and the screenshot below shows the result at the end:
[C#]
public
class
OrderType
{
private
ICollection<Order> orders;
ICollection<Shipper> shippers;
OrderType()
this
.orders =
new
HashSet<Order>();
.shippers =
HashSet<Shipper>();
}
int
OrderTypeId {
get
;
set
; }
virtual
ICollection<Order> Orders
return
.orders;
.orders = value;
ICollection<Shipper> Shippers
.shippers;
.shippers = value;
string
Description {
[VB]
Public
Class
Private
m_orders
As
ICollection(Of Order)
m_shippers
ICollection(Of Shipper)
Sub
New
()
Me
.m_orders =
HashSet(Of Order)()
.m_shippers =
HashSet(Of Shipper)()
End
Property
OrderTypeId()
Integer
Get
Return
m_OrderTypeId
Set
(value
)
m_OrderTypeId = Value
Overridable
Orders()
.m_orders
ICollection(Of Order))
.m_orders = value
Shippers()
.m_shippers
ICollection(Of Shipper))
.m_shippers = value
Description()
String
m_Description
m_Description = Value
Order
OrderId {
OrderType OrderType {
bool
IsFinished {
OrderId()
m_OrderId
m_OrderId = Value
m_OrderType
OrderType)
m_OrderType = Value
)
IsFinished()
Boolean
m_IsFinished
m_IsFinished = Value
Shipper
ShipperId {
Name {
Address {
ShipperId()
m_ShipperId
m_ShipperId = Value
Name()
m_Name
m_Name = Value
Address()
m_Address
m_Address = Value
interface
IGenericRepository<T> where T :
IQueryable<T> All();
IQueryable<T> SearchFor(Expression<Func<T,
>> conditions);
void
Add(T entity);
Update(T entity);
Delete(T entity);
Detach(T entity);
Interface
IGenericRepository(Of T
Function
All()
IQueryable(Of T)
SearchFor(conditions
Expression(Of Func(Of T,
)))
Add(entity
T)
Update(entity
Delete(entity
Detach(entity
IRadGridViewEFCodeFirstContext
IDbSet<Order> Orders {
IDbSet<OrderType> OrderTypes {
IDbSet<Shipper> Shippers {
IDbSet<T> Set<T>() where T :
DbEntityEntry<T> Entry<T>(T entity) where T :
SaveChanges();
IDbSet(Of Order)
OrderTypes()
IDbSet(Of OrderType)
IDbSet(Of Shipper)
[
](Of T
)()
IDbSet(Of T)
Entry(Of T
)(entity
DbEntityEntry(Of T)
SaveChanges()
IRadGridViewEFCodeFirstData
IGenericRepository<Order> Orders {
IGenericRepository<OrderType> OrderTypes {
IGenericRepository<Shipper> Shippers {
ReadOnly
IGenericRepository(Of Order)
IGenericRepository(Of OrderType)
IGenericRepository(Of Shipper)
RadGridViewEFCodeFirstContext : DbContext, IRadGridViewEFCodeFirstContext
RadGridViewEFCodeFirstContext()
:
base
(
"RadGridViewEFCodeFirstConnection"
Database.SetInitializer(
MigrateDatabaseToLatestVersion<RadGridViewEFCodeFirstContext, Configuration>());
.Set<T>();
.SaveChanges();
RadGridViewEFCodeFirstContext
Inherits
DbContext
Implements
MyBase
.
MigrateDatabaseToLatestVersion(Of RadGridViewEFCodeFirstContext, Migrations.Configuration)())
IRadGridViewEFCodeFirstContext.Orders
m_Orders
IDbSet(Of Order))
m_Orders = value
IRadGridViewEFCodeFirstContext.OrderTypes
m_OrderTypes
IDbSet(Of OrderType))
m_OrderTypes = value
IRadGridViewEFCodeFirstContext.Shippers
m_Shippers
IDbSet(Of Shipper))
m_Shippers = value
Shadows
IRadGridViewEFCodeFirstContext.
.[
](Of T)()
IRadGridViewEFCodeFirstContext.SaveChanges
.SaveChanges()
Overloads
Infrastructure.DbEntityEntry(Of T)
IRadGridViewEFCodeFirstContext.Entry
.[Entry](Of T)(entity)
RadGridViewEFCodeFirstRepository<T> : IGenericRepository<T> where T :
IRadGridViewEFCodeFirstContext context;
IDbSet<T>
RadGridViewEFCodeFirstRepository(IRadGridViewEFCodeFirstContext context)
.context = context;
= context.Set<T>();
IQueryable<T> All()
.AsQueryable();
>> conditions)
.All().Where(conditions);
Add(T entity)
.Add(entity);
Update(T entity)
var entry = AttachIfDetached(entity);
entry.State = EntityState.Modified;
Delete(T entity)
entry.State = EntityState.Deleted;
Detach(T entity)
var entry =
.context.Entry(entity);
entry.State = EntityState.Detached;
DbEntityEntry AttachIfDetached(T entity)
if
(entry.State == EntityState.Detached)
.Attach(entity);
entry;
RadGridViewEFCodeFirstRepository(Of T
IGenericRepository(Of T)
context
[set]
(context
IRadGridViewEFCodeFirstContext)
.context = context
.[set] = context.[
IGenericRepository(Of T).All
.[set].AsQueryable()
IGenericRepository(Of T).SearchFor
.All().Where(conditions)
IGenericRepository(Of T).Add
.[set].Add(entity)
IGenericRepository(Of T).Update
Dim
entry = AttachIfDetached(entity)
entry.State = EntityState.Modified
IGenericRepository(Of T).Delete
entry.State = EntityState.Deleted
IGenericRepository(Of T).Detach
entry =
.context.Entry(entity)
entry.State = EntityState.Detached
AttachIfDetached(entity
DbEntityEntry
If
Then
.[set].Attach(entity)
entry
RadGridViewEFCodeFirstData : IRadGridViewEFCodeFirstData
IDictionary<Type,
object
> repositories;
RadGridViewEFCodeFirstData()
RadGridViewEFCodeFirstContext())
RadGridViewEFCodeFirstData(IRadGridViewEFCodeFirstContext context)
.repositories =
Dictionary<Type,
>();
IGenericRepository<Order> Orders
.GetRepository<Order>();
IGenericRepository<OrderType> OrderTypes
.GetRepository<OrderType>();
IGenericRepository<Shipper> Shippers
.GetRepository<Shipper>();
.context.SaveChanges();
IGenericRepository<T> GetRepository<T>() where T :
var typeOfModel =
typeof
(T);
(!
.repositories.ContainsKey(typeOfModel))
Type type =
(RadGridViewEFCodeFirstRepository<T>);
.repositories.Add(typeOfModel, Activator.CreateInstance(type,
.context));
(IGenericRepository<T>)
.repositories[typeOfModel];
RadGridViewEFCodeFirstData
repositories
IDictionary(Of Type,
Object
Dictionary(Of Type,
IRadGridViewEFCodeFirstData.Orders
.GetRepository(Of Order)()
IRadGridViewEFCodeFirstData.OrderTypes
.GetRepository(Of OrderType)()
IRadGridViewEFCodeFirstData.Shippers
.GetRepository(Of Shipper)()
IRadGridViewEFCodeFirstData.SaveChanges
.context.SaveChanges()
GetRepository(Of T
typeOfModel =
GetType
(T)
Not
.repositories.ContainsKey(typeOfModel)
type =
(RadGridViewEFCodeFirstRepository(Of T))
.context))
DirectCast
.repositories(typeOfModel), IGenericRepository(Of T))
DataGenerator
static
PopulateData(IRadGridViewEFCodeFirstData data)
for
i = 1; i <= 100; i++)
OrderType orderType =
OrderTypeId = i,
Description =
"Test"
+ i
};
Order order =
Order()
OrderId = i,
"Description"
+ i,
OrderTypeId = orderType.OrderTypeId
Shipper shipper =
Shipper()
ShipperId = i,
Name =
"Name "
OrderTypeId = orderType.OrderTypeId,
Address =
"Address "
data.OrderTypes.Add(orderType);
data.Orders.Add(order);
data.Shippers.Add(shipper);
(i % 100 == 0)
data.SaveChanges();
Shared
PopulateData(data
IRadGridViewEFCodeFirstData)
For
i
= 1
To
100
orderType
With
.OrderTypeId = i,
.Description =
& i
order
.OrderId = i, _
& i,
.OrderTypeId = orderType.OrderTypeId
shipper
.ShipperId = i,
.Name =
"Name"
.OrderTypeId = orderType.OrderTypeId,
.Address =
"Address"
data.OrderTypes.Add(orderType)
data.Orders.Add(order)
data.Shippers.Add(shipper)
Mod
10 = 0
data.SaveChanges()
Next
5. In our client application we will setup the RadGridView control in hierarchy feeding the templates with data coming from different repositories:
partial
Form1 : Form
IRadGridViewEFCodeFirstData data;
Form1()
InitializeComponent();
.data =
RadGridViewEFCodeFirstData();
(!data.OrderTypes.All().Any() || !data.Orders.All().Any() || !data.Shippers.All().Any())
DataGenerator.PopulateData(
.data);
.SetUpGrid();
.FormClosing += Form1_FormClosing;
Form1_FormClosing(
sender, FormClosingEventArgs e)
.data.SaveChanges();
SetUpGrid()
((IDbSet<OrderType>)
.data.OrderTypes.All()).Load();
.radGridView1.DataSource = ((IDbSet<OrderType>)
.data.OrderTypes.All()).Local.ToBindingList();
.radGridView1.Columns[
"Orders"
].IsVisible =
false
"Shippers"
.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
GridViewTemplate ordersTemplate =
GridViewTemplate();
ordersTemplate.Caption =
radGridView1.MasterTemplate.Templates.Add(ordersTemplate);
((IDbSet<Order>)
.data.Orders.All()).Load();
ordersTemplate.DataSource = ((IDbSet<Order>)
.data.Orders.All()).Local.ToBindingList();
ordersTemplate.Columns[
"OrderType"
ordersTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
GridViewRelation relation =
GridViewRelation(radGridView1.MasterTemplate);
relation.ChildTemplate = ordersTemplate;
relation.RelationName =
"OrderTypesOrders"
relation.ParentColumnNames.Add(
"OrderTypeId"
);
relation.ChildColumnNames.Add(
radGridView1.Relations.Add(relation);
GridViewTemplate shippersTemplate =
shippersTemplate.Caption =
radGridView1.MasterTemplate.Templates.Add(shippersTemplate);
((IDbSet<Shipper>)
.data.Shippers.All()).Load();
shippersTemplate.DataSource = ((IDbSet<Shipper>)
.data.Shippers.All()).Local.ToBindingList();
shippersTemplate.Columns[
shippersTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
GridViewRelation relation2 =
relation2.ChildTemplate = shippersTemplate;
relation2.RelationName =
"OrderTypesShippers"
relation2.ParentColumnNames.Add(
relation2.ChildColumnNames.Add(
radGridView1.Relations.Add(relation2);
[ VB]
Form1
Form
data
InitializeComponent()
data.OrderTypes.All().Any()
OrElse
data.Orders.All().Any()
data.Shippers.All().Any() The
.data)
.SetUpGrid()
AddHandler
.FormClosing,
AddressOf
Form1_FormClosing
Form1_FormClosing(sender
, e
FormClosingEventArgs)
.data.SaveChanges()
.data.OrderTypes.All(), IDbSet(Of OrderType)).Load()
.RadGridView1.DataSource =
.data.OrderTypes.All(), IDbSet(Of OrderType)).Local.ToBindingList()
.RadGridView1.Columns(
).IsVisible =
False
.RadGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill
ordersTemplate
GridViewTemplate()
.RadGridView1.MasterTemplate.Templates.Add(ordersTemplate)
.data.Orders.All(), IDbSet(Of Order)).Load()
ordersTemplate.DataSource =
.data.Orders.All(), IDbSet(Of Order)).Local.ToBindingList()
ordersTemplate.Columns(
ordersTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill
relation
GridViewRelation(RadGridView1.MasterTemplate)
relation.ChildTemplate = ordersTemplate
RadGridView1.Relations.Add(relation)
shippersTemplate
.RadGridView1.MasterTemplate.Templates.Add(shippersTemplate)
.data.Shippers.All(), IDbSet(Of Shipper)).Load()
shippersTemplate.DataSource =
.data.Shippers.All(), IDbSet(Of Shipper)).Local.ToBindingList()
shippersTemplate.Columns(
shippersTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill
relation2
relation2.ChildTemplate = shippersTemplate
.RadGridView1.Relations.Add(relation2)
Resources Buy Try