1-实体框架数据层(基础知识)
在本文中,我们将使用一个名为 Company
的简单数据库,其中包含两个表:
[dbo]。[分类]([CategoryID],[CategoryName])
[dbo]。[产品]([ProductID],[CategoryID],[ProductName])
1-1 生成实体框架代码
在这一层,我们生成实体框架代码(在项目库中)(请参阅本文 ,如何做到这一点)然后你将拥有以下类
public partial class CompanyContext : DbContext
public partial class Product
public partial class Category
1-2 创建基本界面
我们将为我们的基础功能创建一个界面
public interface IDbRepository : IDisposable
{
#region Tables and Views functions
IQueryable<TResult> GetAll<TResult>(bool noTracking = true) where TResult : class;
TEntity Add<TEntity>(TEntity entity) where TEntity : class;
TEntity Delete<TEntity>(TEntity entity) where TEntity : class;
TEntity Attach<TEntity>(TEntity entity) where TEntity : class;
TEntity AttachIfNot<TEntity>(TEntity entity) where TEntity : class;
#endregion Tables and Views functions
#region Transactions Functions
int Commit();
Task<int> CommitAsync(CancellationToken cancellationToken = default(CancellationToken));
#endregion Transactions Functions
#region Database Procedures and Functions
TResult Execute<TResult>(string functionName, params object[] parameters);
#endregion Database Procedures and Functions
}
1-3 实现基本接口
/// <summary>
/// Implementing basic tables, views, procedures, functions, and transaction functions
/// Select (GetAll), Insert (Add), Delete, and Attach
/// No Edit (Modify) function (can modify attached entity without function call)
/// Executes database procedures or functions (Execute)
/// Transaction functions (Commit)
/// More functions can be added if needed
/// </summary>
/// <typeparam name="TEntity">Entity Framework table or view</typeparam>
public class DbRepository : IDbRepository
{
#region Protected Members
protected DbContext _dbContext;
#endregion Protected Members
#region Constractors
/// <summary>
/// Repository constructor
/// </summary>
/// <param name="dbContext">Entity framework databse context</param>
public DbRepository(DbContext dbContext)
{
_dbContext = dbContext;
ConfigureContext();
}
#endregion Constractors
#region IRepository Implementation
#region Tables and Views functions
/// <summary>
/// Query all
/// Set noTracking to true for selecting only (read-only queries)
/// Set noTracking to false for insert, update, or delete after select
/// </summary>
public virtual IQueryable<TResult> GetAll<TResult>(bool noTracking = true) where TResult : class
{
var entityDbSet = GetDbSet<TResult>();
if (noTracking)
return entityDbSet.AsNoTracking();
return entityDbSet;
}
public virtual TEntity Add<TEntity>(TEntity entity) where TEntity : class
{
return GetDbSet<TEntity>().Add(entity);
}
/// <summary>
/// Delete loaded (attached) or unloaded (Detached) entitiy
/// No need to load object to delete it
/// Create new object of TEntity and set the id then call Delete function
/// </summary>
/// <param name="entity">TEntity</param>
/// <returns></returns>
public virtual TEntity Delete<TEntity>(TEntity entity) where TEntity : class
{
if (_dbContext.Entry(entity).State == EntityState.Detached)
{
_dbContext.Entry(entity).State = EntityState.Deleted;
return entity;
}
else
return GetDbSet<TEntity>().Remove(entity);
}
public virtual TEntity Attach<TEntity>(TEntity entity) where TEntity : class
{
return GetDbSet<TEntity>().Attach(entity);
}
public virtual TEntity AttachIfNot<TEntity>(TEntity entity) where TEntity : class
{
if (_dbContext.Entry(entity).State == EntityState.Detached)
return Attach(entity);
return entity;
}
#endregion Tables and Views functions
#region Transactions Functions
/// <summary>
/// Saves all changes made in this context to the underlying database.
/// </summary>
/// <returns>The number of objects written to the underlying database.</returns>
public virtual int Commit()
{
return _dbContext.SaveChanges();
}
/// <summary>
/// Asynchronously saves all changes made in this context to the underlying database.
/// </summary>
/// <param name="cancellationToken">A System.Threading.CancellationToken to observe while waiting for the task to complete.</param>
/// <returns>A task that represents the asynchronous save operation. The task result contains the number of objects written to the underlying database.</returns>
public virtual Task<int> CommitAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return _dbContext.SaveChangesAsync(cancellationToken);
}
#endregion Transactions Functions
#region Database Procedures and Functions
/// <summary>
/// Executes any function in the context
/// use to call database procesdures and functions
/// </summary>>
/// <typeparam name="TResult">return function type</typeparam>
/// <param name="functionName">context function name</param>
/// <param name="parameters">context function parameters in same order</param>
public virtual TResult Execute<TResult>(string functionName, params object[] parameters)
{
MethodInfo method = _dbContext.GetType().GetMethod(functionName);
return (TResult)method.Invoke(_dbContext, parameters);
}
#endregion Database Procedures and Functions
#endregion IRepository Implementation
#region IDisposable Implementation
public void Dispose()
{
_dbContext.Dispose();
}
#endregion IDisposable Implementation
#region Protected Functions
/// <summary>
/// Set Context Configuration
/// </summary>
protected virtual void ConfigureContext()
{
// set your recommended Context Configuration
_dbContext.Configuration.LazyLoadingEnabled = false;
}
#endregion Protected Functions
#region Private Functions
private DbSet<TEntity> GetDbSet<TEntity>() where TEntity : class
{
return _dbContext.Set<TEntity>();
}
#endregion Private Functions
}