预备知识:
1、了解反射技术
2、了解C#3.0中扩展方法,分布类,Linq to object,Linq to sql
3、了解ASP.NET MVC
在项目中每添加一个表往往都要添加一套增删改代码,而且这些代码很多情况下都很相似,这里我们给出一个通用的解决方案供大家参考。
一、准备工作:
这里我们先要在数据库中添加两个表News和User如下图:然后拖到dbml中生成实体类。
这里我们先准备一个接口:ICommonTable
public interface ICommonTable
{
int id { get; set; }
}
然后让News和User实体都继承于此接口
public partial class News : ICommonTable
{
}
public partial class User : ICommonTable
{
}
二、通用删除操作
分别添加NewsList.aspx和UserList.aspx两个view,添加方式参见ASP.NET MVC实践系列2-简单应用
在这两个View中加入删除链接:
<%= Html.ActionLink("删除", "Delete", new { key = item.id, partialName="News" })%>
和
<%= Html.ActionLink("删除", "Delete", new { key = item.id, partialName="User" })%>
然后添加一个Controller:
{
RepositoryBase repositoryBase = new RepositoryBase(partialName);
repositoryBase.Delete(key ?? 0);
return RedirectToAction(partialName + "List");//返回到list
}
{
public Type EntityType { get; private set; }
public RepositoryBase(string entityType)
{
Type type = GetBllTypeByName(entityType);
EntityType = type;
}
public ICommonTable CreateNew()
{
return (ICommonTable)Activator.CreateInstance(EntityType);
}
/// <summary>
/// 通过字符串获得其Type
/// </summary>
/// <param name="typeName"></param>
/// <returns></returns>
private static Type GetBllTypeByName(string typeName)
{
Type type = null;
var ass = AppDomain.CurrentDomain.GetAssemblies()
.Where(p => p.FullName.Contains("CommonCEDemo"));
foreach (var a in ass)
{
type = a.GetTypes().Where(p => p.Name == typeName).FirstOrDefault();
if (type != null)
break;
}
if (type == null)
{
throw new Exception("类型未定义:" + typeName);
}
return type;
}
public RepositoryBase(Type entityType)
{
EntityType = entityType;
}
public ICommonTable Get(int id)
{
DBDataContext db = Context.GetContext();
return db.GetTable(EntityType).Cast<ICommonTable>().FirstOrDefault(p => p.id == id);
}
public void Delete(int id)
{
ICommonTable bllTable = Get(id);
Context.GetContext().GetTable(EntityType).DeleteOnSubmit(bllTable);
Context.GetContext().SubmitChanges();
}
}
{
static DBDataContext context;
static Context()
{
if (context==null)
{
context = new DBDataContext();
}
}
public static DBDataContext GetContext()
{
return context;
}
}
<%Html.RenderPartial(ViewData["PartialName"].ToString()); %>
</asp:Content>
{
ViewData["PartialName"] = partialName;
RepositoryBase repositoryBase = new RepositoryBase(partialName);
ICommonTable table;
if (key == null)
{
table = repositoryBase.CreateNew();
}
else
{
table = repositoryBase.Get(key ?? 0);
}
return View("CreateEditView", table);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreateEditView(string partialName, int? key, FormCollection formCollection)
{
RepositoryBase repositoryBase = new RepositoryBase(partialName);
ICommonTable bllTable;
if (key == null)
{
bllTable = repositoryBase.CreateNew();
}
else
{
bllTable = repositoryBase.Get(key ?? 0);
}
this.UpdateModel(bllTable, true);
if (key == null)
{
Context.GetContext().GetTable(repositoryBase.EntityType).InsertOnSubmit(bllTable);
}
Context.GetContext().SubmitChanges();
return RedirectToAction(partialName+"List");//返回到list
}
if (model == null) {
throw new ArgumentNullException("model");
}
if (valueProvider == null) {
throw new ArgumentNullException("valueProvider");
}
Predicate<string> propertyFilter = propertyName => BindAttribute.IsPropertyAllowed(propertyName, includeProperties, excludeProperties);
IModelBinder binder = Binders.GetBinder(typeof(TModel));
ModelBindingContext bindingContext = new ModelBindingContext() {
Model = model,
ModelName = prefix,
ModelState = ModelState,
ModelType = typeof(TModel),
PropertyFilter = propertyFilter,
ValueProvider = valueProvider
};
binder.BindModel(ControllerContext, bindingContext);
return ModelState.IsValid;
}
{
/// <summary>
/// 更新时是否按照当前类型进行更新
/// </summary>
/// <typeparam name="TModel"></typeparam>
/// <param name="controller"></param>
/// <param name="model"></param>
/// <param name="isEx"></param>
public static void UpdateModel<TModel>(this Controller controller, TModel model, bool isExtension) where TModel : class
{
if (isExtension)
{
Predicate<string> propertyFilter = propertyName => IsPropertyAllowed(propertyName, null, null);
IModelBinder binder = ModelBinders.Binders.GetBinder(model.GetType());
ModelBindingContext bindingContext = new ModelBindingContext()
{
Model = model,
ModelName = null,
ModelState = controller.ModelState,
ModelType = model.GetType(),
PropertyFilter = propertyFilter,
ValueProvider = controller.ValueProvider
};
binder.BindModel(controller.ControllerContext, bindingContext);
}
else
{
throw new Exception("isExtension不能选择false");
}
}
private static bool IsPropertyAllowed(string propertyName, string[] includeProperties, string[] excludeProperties)
{
bool includeProperty = (includeProperties == null) || (includeProperties.Length == 0) || includeProperties.Contains(propertyName, StringComparer.OrdinalIgnoreCase);
bool excludeProperty = (excludeProperties != null) && excludeProperties.Contains(propertyName, StringComparer.OrdinalIgnoreCase);
return includeProperty && !excludeProperty;
}
}