C# Entity Framework Code-first
▌Introduction
This
articles was inspired by WASICHRIS’ article:
Since I
have a UOW
(Unit of work) pattern on my Entity
Framework 6 library, every POCO entity should inherits the base entity class
and has its own CRUD service class as following,
PS. We need to create a Partial class which inherits UowEntity in DB-first.
However
the time for creating the Partial classes and Service classes for a whole new
DB-first data model (ADO.NET
Entity Data Model) is expensive,
so that we will use T4 to generate them automatically.
▋Related articles
▌Environment
▋Visual Studio 2017 community
▋Entity Framework 6.1.3
▌Implement
▋T4 for Models
OK, the code is complex and I won’t give too much explanation
on it.
The flow is,
1. Load .edmx and get all
entity types (EntityType)
from it
2. For every EntityType,
generate a .cs file with same class name (if not exists)
3. Write namespaces and
partial class structure into the .cs file
1. The partial class created
from EdmxModel-metadata.tt
inherits UowEntity
and defines the MetadataType
2. The partial class created
from EdmxModel-simple.tt only
inherits UowEntity
Assume that there is a POCO: MyModel in EDMX, the
above T4 will generate:
1. MyModels.cs (by EdmxModel-simple.tt)
2. MyModelsMetadata.cs (by EdmxModel-metadata.tt)
And their contents:
▋MyModels.cs
namespace JB.Infra.Util.EF.Models
{
using System;
using System.Collections.Generic;
public partial class MyModels
{
public int Id { get; set; }
public string Name { get; set; }
public string Department { get; set; }
}
}
▋MyModelsMetadata.cs
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using JB.Infra.Util.EF.Entity;
namespace JB.Infra.Utility.EF.DbFirst.UnitTest.Models
{
/// <summary>
/// MyModels class
/// </summary>
[Description("My
Models")]
[MetadataType(typeof(MyModelsMetadata))]
public partial class MyModels : UowEntity
{
}
/// <summary>
/// MyModels Metadata class
/// </summary>
internal class MyModelsMetadata
{
/// <summary>
/// Id
/// </summary>
[DisplayName("Id")]
[Description("Id")]
[Required(ErrorMessage = "Id is required")]
public int Id { get; set; }
/// skip ...
/// skip ...
▋T4 for Services
Same process on generating CRUD Service class.
Notice the relative path of .edmx is updated to
“../Models”
Result:
▌Reference
沒有留言:
張貼留言