【C#编程最佳实践 八】MVC流程实践
近期参与了工作台开发任务,亲身实践了mvc一个流程:(Model层)创建数据表—(Model层)创建Entity实体类—(Model层)创建数据表和实体的映射关系或调用通用的映射关系—(Model层)创建存储过程—(Model层)创建Dao层代码—(Model层)创建Provider层代码—(Controller层)在控制层写业务逻辑接口调用Model的provider,并返回给前端(View)—(View层)前端。体会了MVC全流程实践,也体会了团队合作如何实现。
Model层
Model层相当于一块功能的封装,为控制层接口提供服务。一般会涉及到对数据表的操作,那么一般会涉及到以下操作。
创建数据表
USE [***LandingSite]
GO
/****** Object: Table [dbo].[WorkBenchScene] Script Date: 2017/12/22 11:39:25 ******/
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[WorkBenchScene]( [ID] [uniqueidentifier] NOT NULL, [Name] [nvarchar](200) NOT NULL, [PID] [uniqueidentifier] NULL, [Application] [nvarchar](50) NULL, [TenantID] [int] NULL, [MetaObjectName] [varchar](100) NOT NULL, [CreatedBy] [int] NOT NULL, [CreatedTime] [datetime] NOT NULL, [ModifiedBy] [int] NULL, [ModifiedTime] [datetime] NULL, [ProcessJson] [nvarchar](max) NOT NULL, [IsEnabled] [bit] NULL, CONSTRAINT [PK_WorkBenchScene] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO
/****** Script for SelectTopNRows command from SSMS ******/
SELECT TOP (1000) [ID]
,[Name]
,[PID]
,[Application]
,[TenantID]
,[MetaObjectName]
,[CreatedBy]
,[CreatedTime]
,[ModifiedBy]
,[ModifiedTime]
,[ProcessJson]
,[IsEnabled]
FROM [***LandingSite].[dbo].[WorkBenchScene]
创建实体类
using System;
using System.Runtime.Serialization;
namespace ***.Implementation.Entity.WorkBench
{
/// <summary>
/// 场景表对应的实体类
/// </summary>
public class WorkBenchScene : BaseEntity
{
/// <summary>
/// 场景名
/// </summary>
[DataMember]
public string Name { get; set; }
/// <summary>
/// 场景父ID
/// </summary>
public Guid PID { get; set; }
/// <summary>
/// 应用名
/// </summary>
public string Application { get; set; }
/// <summary>
/// 租户ID
/// </summary>
public int TenantID { get; set; }
/// <summary>
/// 实体名
/// </summary>
public string MetaObjectName { get; set; }
/// <summary>
/// 创建人
/// </summary>
public int CreatedBy { get; set; }
/// <summary>
/// 修改人
/// </summary>
public int ModifiedBy { get; set; }
/// <summary>
/// 修改时间
/// </summary>
public DateTime ModifiedTime { get; set; }
/// <summary>
/// 流程json字符串ProcessJson
/// </summary>
public string ProcessJson { get; set; }
/// <summary>
/// 是否启用
/// </summary>
public bool IsEnabled { get; set; }
}
}
创建数据表和实体的映射关系
创建自定义映射关系
#region 私有 mapper
private ***.Data.MapperDelegates.RecordMapper<API> GetMapper()
{
return delegate (IRecord record, API model)
{
model.ID = record.Get<Guid>("ID");
model.Application = record.GetOrDefault<string>("Application", string.Empty);
model.ApiType = record.GetOrDefault<int>("ApiType", 0);
model.ResourceCode = record.GetOrDefault<string>("ResourceCode", string.Empty);
model.ResourceName = record.GetOrDefault<string>("ResourceName", string.Empty);
model.GetListAPI = record.GetOrDefault<string>("GetListAPI", string.Empty);
model.ImportDataAPI = record.GetOrDefault<string>("ImportDataAPI", string.Empty);
model.Enabled = record.GetOrDefault<bool>("Enabled", true);
model.CreatedTime = record.GetOrDefault<DateTime>("CreatedTime", DateTime.MinValue);
model.ShowFields = record.GetOrDefault("ShowFields", string.Empty);
model.WhiteList = record.GetOrDefault("WhiteList", string.Empty);
};
}
#endregion 私有 mapper
调用默认的映射关系
注意,默认的映射规则,实体的属性名和数据表的列名一定要对的上。
protected ***.Data.MapperDelegates.RecordMapper<T> GetMapper()
{
return delegate (IRecord record, T model)
{
if (Properties != null)
{
foreach (var item in Properties)
{
try
{
SetValue(item, record, ref model);
}
catch (Exception e)
{
System.Console.WriteLine($"error: {EntityName}.{ item.Name}"); //todo ....logger
}
}
}
};
}
private static void SetValue(PropertyInfo item, IRecord record, ref T model)
{
var fieldName = item.Name;
switch (item.PropertyType.FullName)
{
case "System.Int32":
item.SetValue(model, record.GetOrDefault<int>(fieldName, 0));
break;
case "System.String":
item.SetValue(model, record.GetOrDefault<string>(fieldName, string.Empty));
break;
case "System.Boolean":
item.SetValue(model, record.GetOrDefault<Boolean>(fieldName, false));
break;
case "System.DateTime":
item.SetValue(model, record.GetOrDefault<DateTime>(fieldName, DateTime.MinValue));
break;
case "System.Float":
item.SetValue(model, record.GetOrDefault<float>(fieldName, 0));
break;
case "System.Double":
item.SetValue(model, record.GetOrDefault<Double>(fieldName, 0));
break;
case "System.Guid":
item.SetValue(model, record.GetOrDefault<Guid>(fieldName, Guid.Empty));
break;
default:
throw new TypeLoadException($"未知字段类型异常.fieldName:{fieldName},type:{item.PropertyType.FullName}");
}
}
创建存储过程
USE [***LandingSite]
GO
/****** Object: StoredProcedure [dbo].[WorkBenchScene_GetByMetaObjectName] Script Date: 2017/12/22 12:09:45 ******/
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- Author: tianmaolin -- Create date: 2017-12-22 -- Description: 根据实体编码获取场景 -- ============================================= ALTER PROCEDURE [dbo].[WorkBenchScene_GetByMetaObjectName]( @MetaObjectName varchar(100) ) AS SELECT * FROM dbo.WorkBenchScene where MetaObjectName=@MetaObjectName
创建Dao层代码
创建Provider层代码
Controller层
/// <summary>
/// 公有方法:通过实体名获取场景名和场景ID列表组
/// </summary>
/// <param name="metaObjectName"></param>
/// <returns></returns>
[HttpGet] //通过get方式获取
public JsonResult GetByMetaObjectName(string metaObjectName)
{
if (!string.IsNullOrEmpty(metaObjectName))
{
List<WorkBenchScene> lw = WorkBenchSceneProvider.Instance.GetByMetaObjectName(metaObjectName); //获取场景列表
if (lw == null || lw.Count == 0)
{
return Json(new Helper.OperationResult { code = (int)CodeType.Failure, message = "场景列表获取失败" }, JsonRequestBehavior.AllowGet);
}
List<WorkBenchDic> list = new List<WorkBenchDic>();
foreach (var item in lw)
{
list.Add(new WorkBenchDic(item.ID.ToString(), item.Name));
}
return Json(new Helper.OperationResult { code = (int)CodeType.Success, message = "获取成功", param = list }, JsonRequestBehavior.AllowGet);
}
return Json(new Helper.OperationResult { code = (int)CodeType.Failure, message = "参数为空" }, JsonRequestBehavior.AllowGet);
}
/// <summary>
/// 公有方法:通过场景id获取该场景详情
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet]
public JsonResult GetByID(Guid id)
{
if (!string.IsNullOrEmpty(id.ToString()))
{
WorkBenchScene wbs = WorkBenchSceneProvider.Instance.GetById(id); //获取确定场景
if (wbs == null)
{
return Json(new Helper.OperationResult { code = (int)CodeType.Failure, message = "场景获取失败" }, JsonRequestBehavior.AllowGet);
}
return Json(new Helper.OperationResult { code = (int)CodeType.Success, message = "获取成功", param = wbs.ProcessJson }, JsonRequestBehavior.AllowGet);
}
return Json(new Helper.OperationResult { code = (int)CodeType.Failure, message = "参数为空" }, JsonRequestBehavior.AllowGet);
}
View层
SettingValue是页面