之前我老大去网上找了一个DAL里面操作数据库的通用类:

    public class DALHelper
{
public static List<T> Search<T>() where T : SH_SetBase
{
using (var db = new ShopContext())
{
var dbSet = GetDBSet(db, typeof(T)) as DbSet<T>;
if (typeof(T).IsSubclassOf(typeof(SH_SetBase)))
{
return dbSet.Where(o => !o.IsDelete).ToList();
}
return dbSet.ToList();
}
} public static List<T> Search<T>(Expression<Func<T, bool>> where) where T : SH_Base
{
using (ShopContext db = new ShopContext())
{
DbSet<T> dbSet = GetDBSet(db, typeof(T)) as DbSet<T>;
if (typeof(T).IsSubclassOf(typeof(SH_SetBase)))
{
Expression<Func<T, bool>> where2 = (o => (o as SH_SetBase).IsDelete == false);
var invokedExpr = Expression.Invoke(where2, where.Parameters.Cast<Expression>());
Expression<Func<T, bool>> where3 = Expression.Lambda<Func<T, bool>>(Expression.And(where.Body, invokedExpr), where.Parameters);
return dbSet.Where(where3.Compile()).ToList();
}
return dbSet.Where(where).ToList();
}
} public static List<T> Search<T>(Expression<Func<T, bool>> where, PageContent pageContent) where T : SH_Base
{
using (ShopContext db = new ShopContext())
{
DbSet<T> dbSet = GetDBSet(db, typeof(T)) as DbSet<T>;
if (typeof(T).IsSubclassOf(typeof(SH_SetBase)))
{
Expression<Func<T, bool>> where2 = (o => (o as SH_SetBase).IsDelete == false);
var invokedExpr = Expression.Invoke(where2, where.Parameters.Cast<Expression>());
Expression<Func<T, bool>> where3 = Expression.Lambda<Func<T, bool>>(Expression.And(where.Body, invokedExpr), where.Parameters);
where = where3;
}
pageContent.TotalLogs = Count<T>(where);
return dbSet.Where(where.Compile()).Skip((pageContent.PageIndex - 1) * pageContent.PageSize).Take(pageContent.PageSize).ToList();
}
} public static List<T> Search<T>(Expression<Func<T, object>> include, Expression<Func<T, bool>> where) where T : SH_Base
{
using (ShopContext db = new ShopContext())
{
DbSet<T> dbSet = GetDBSet(db, typeof(T)) as DbSet<T>;
if (typeof(T).IsSubclassOf(typeof(SH_SetBase)))
{
Expression<Func<T, bool>> where2 = (o => (o as SH_SetBase).IsDelete == false);
var invokedExpr = Expression.Invoke(where2, where.Parameters.Cast<Expression>());
Expression<Func<T, bool>> where3 = Expression.Lambda<Func<T, bool>>(Expression.And(where.Body, invokedExpr), where.Parameters);
return dbSet.Include(include).Where(where3.Compile()).ToList();
}
return dbSet.Include(include).Where(where).ToList();
}
} public static List<T> Search<T>(Expression<Func<T, object>> include, Expression<Func<T, bool>> where, PageContent pageContent) where T : SH_Base
{
using (ShopContext db = new ShopContext())
{
DbSet<T> dbSet = GetDBSet(db, typeof(T)) as DbSet<T>;
if (typeof(T).IsSubclassOf(typeof(SH_SetBase)))
{
Expression<Func<T, bool>> where2 = (o => (o as SH_SetBase).IsDelete == false);
var invokedExpr = Expression.Invoke(where2, where.Parameters.Cast<Expression>());
Expression<Func<T, bool>> where3 = Expression.Lambda<Func<T, bool>>(Expression.And(where.Body, invokedExpr), where.Parameters);
where = where3;
}
pageContent.TotalLogs = Count<T>(where);
return dbSet.Include(include).Where(where.Compile()).Skip((pageContent.PageIndex - 1) * pageContent.PageSize).Take(pageContent.PageSize).ToList();
}
} public static List<T> Search<T>(Expression<Func<T, bool>> where, PageContent pageContent, Expression<Func<T, object>> order, bool isAsc) where T : SH_Base
{
using (ShopContext db = new ShopContext())
{
DbSet<T> dbSet = GetDBSet(db, typeof(T)) as DbSet<T>;
if (typeof(T).IsSubclassOf(typeof(SH_SetBase)))
{
Expression<Func<T, bool>> where2 = (o => (o as SH_SetBase).IsDelete == false);
var invokedExpr = Expression.Invoke(where2, where.Parameters.Cast<Expression>());
Expression<Func<T, bool>> where3 = Expression.Lambda<Func<T, bool>>(Expression.And(where.Body, invokedExpr), where.Parameters);
where = where3;
}
pageContent.TotalLogs = Count<T>(where);
if (isAsc)
return dbSet.Where(where.Compile()).OrderBy(order.Compile()).Skip((pageContent.PageIndex - 1) * pageContent.PageSize).Take(pageContent.PageSize).ToList();
else
return dbSet.Where(where.Compile()).OrderByDescending(order.Compile()).Skip((pageContent.PageIndex - 1) * pageContent.PageSize).Take(pageContent.PageSize).ToList();
}
} public static List<T> Search<T>(Expression<Func<T, object>> include, Expression<Func<T, bool>> where, PageContent pageContent, Expression<Func<T, object>> order, bool isAsc) where T : SH_Base
{
using (ShopContext db = new ShopContext())
{
DbSet<T> dbSet = GetDBSet(db, typeof(T)) as DbSet<T>;
if (typeof(T).IsSubclassOf(typeof(SH_SetBase)))
{
Expression<Func<T, bool>> where2 = (o => (o as SH_SetBase).IsDelete == false);
var invokedExpr = Expression.Invoke(where2, where.Parameters.Cast<Expression>());
Expression<Func<T, bool>> where3 = Expression.Lambda<Func<T, bool>>(Expression.And(where.Body, invokedExpr), where.Parameters);
where = where3;
}
pageContent.TotalLogs = Count<T>(where);
if (isAsc)
return dbSet.Include(include).Where(where.Compile()).OrderBy(order.Compile()).Skip((pageContent.PageIndex - 1) * pageContent.PageSize).Take(pageContent.PageSize).ToList();
else
return dbSet.Include(include).Where(where.Compile()).OrderByDescending(order.Compile()).Skip((pageContent.PageIndex - 1) * pageContent.PageSize).Take(pageContent.PageSize).ToList();
}
} public static List<T> Search<T>(Expression<Func<T, object>> path1, Expression<Func<T, object>> path2, Expression<Func<T, bool>> where, PageContent pageContent, Expression<Func<T, object>> order, bool isAsc) where T : SH_Base
{
using (ShopContext db = new ShopContext())
{
DbSet<T> dbSet = GetDBSet(db, typeof(T)) as DbSet<T>;
if (typeof(T).IsSubclassOf(typeof(SH_SetBase)))
{
Expression<Func<T, bool>> where2 = (o => (o as SH_SetBase).IsDelete == false);
var invokedExpr = Expression.Invoke(where2, where.Parameters.Cast<Expression>());
Expression<Func<T, bool>> where3 = Expression.Lambda<Func<T, bool>>(Expression.And(where.Body, invokedExpr), where.Parameters);
where = where3;
}
pageContent.TotalLogs = Count<T>(where);
if (isAsc)
return dbSet.Include(path1).Include(path2).Where(where.Compile()).OrderBy(order.Compile()).Skip((pageContent.PageIndex - 1) * pageContent.PageSize).Take(pageContent.PageSize).ToList();
else
return dbSet.Include(path1).Include(path2).Where(where.Compile()).OrderByDescending(order.Compile()).Skip((pageContent.PageIndex - 1) * pageContent.PageSize).Take(pageContent.PageSize).ToList();
}
} public static bool Exist<T>(Expression<Func<T, bool>> where) where T : SH_Base
{
using (ShopContext db = new ShopContext())
{
DbSet<T> dbSet = GetDBSet(db, typeof(T)) as DbSet<T>;
if (typeof(T).IsSubclassOf(typeof(SH_SetBase)))
{
Expression<Func<T, bool>> where2 = (o => (o as SH_SetBase).IsDelete == false);
var invokedExpr = Expression.Invoke(where2, where.Parameters.Cast<Expression>());
Expression<Func<T, bool>> where3 = Expression.Lambda<Func<T, bool>>(Expression.And(where.Body, invokedExpr), where.Parameters);
return dbSet.FirstOrDefault(where3.Compile()) != null;
}
return dbSet.FirstOrDefault(where.Compile()) != null;
}
} public static int Count<T>(Expression<Func<T, bool>> where) where T : SH_Base
{
using (ShopContext db = new ShopContext())
{
DbSet<T> dbSet = GetDBSet(db, typeof(T)) as DbSet<T>;
if (typeof(T).IsSubclassOf(typeof(SH_SetBase)))
{
Expression<Func<T, bool>> where2 = (o => (o as SH_SetBase).IsDelete == false);
var invokedExpr = Expression.Invoke(where2, where.Parameters.Cast<Expression>());
Expression<Func<T, bool>> where3 = Expression.Lambda<Func<T, bool>>(Expression.And(where.Body, invokedExpr), where.Parameters);
return dbSet.Count(where3.Compile());
}
return dbSet.Count(where);
}
} public static decimal Sum<T>(Expression<Func<T, bool>> where, Expression<Func<T, decimal>> selector) where T : SH_Base
{
using (ShopContext db = new ShopContext())
{
DbSet<T> dbSet = GetDBSet(db, typeof(T)) as DbSet<T>;
if (typeof(T).IsSubclassOf(typeof(SH_SetBase)))
{
Expression<Func<T, bool>> where2 = (o => (o as SH_SetBase).IsDelete == false);
var invokedExpr = Expression.Invoke(where2, where.Parameters.Cast<Expression>());
Expression<Func<T, bool>> where3 = Expression.Lambda<Func<T, bool>>(Expression.And(where.Body, invokedExpr), where.Parameters);
return dbSet.Where(where3.Compile()).Sum(selector.Compile());
}
return dbSet.Where(where.Compile()).Sum(selector.Compile());
}
} public static int Sum<T>(Expression<Func<T, bool>> where, Expression<Func<T, int>> selector) where T : SH_Base
{
using (ShopContext db = new ShopContext())
{
DbSet<T> dbSet = GetDBSet(db, typeof(T)) as DbSet<T>;
if (typeof(T).IsSubclassOf(typeof(SH_SetBase)))
{
Expression<Func<T, bool>> where2 = (o => (o as SH_SetBase).IsDelete == false);
var invokedExpr = Expression.Invoke(where2, where.Parameters.Cast<Expression>());
Expression<Func<T, bool>> where3 = Expression.Lambda<Func<T, bool>>(Expression.And(where.Body, invokedExpr), where.Parameters);
return dbSet.Where(where3.Compile()).Sum(selector.Compile());
}
return dbSet.Where(where.Compile()).Sum(selector.Compile());
}
} public static T SearchObject<T>(Expression<Func<T, bool>> where) where T : SH_Base
{
using (ShopContext db = new ShopContext())
{
DbSet<T> dbSet = GetDBSet(db, typeof(T)) as DbSet<T>;
if (typeof(T).IsSubclassOf(typeof(SH_SetBase)))
{
Expression<Func<T, bool>> where2 = (o => (o as SH_SetBase).IsDelete == false);
var invokedExpr = Expression.Invoke(where2, where.Parameters.Cast<Expression>());
Expression<Func<T, bool>> where3 = Expression.Lambda<Func<T, bool>>(Expression.And(where.Body, invokedExpr), where.Parameters);
return dbSet.FirstOrDefault(where3.Compile());
}
return dbSet.FirstOrDefault(where.Compile());
}
} public static T Find<T>(long id) where T : SH_Base
{
using (ShopContext db = new ShopContext())
{
DbSet<T> dbSet = GetDBSet(db, typeof(T)) as DbSet<T>;
if (typeof(T).IsSubclassOf(typeof(SH_SetBase)))
{
SH_SetBase model = dbSet.Find(id) as SH_SetBase;
if (model != null && !model.IsDelete)
return model as T;
}
return dbSet.Find(id) as T;
}
} public static bool Save(SH_Base model)
{
using (ShopContext db = new ShopContext())
{
object dbSet = GetDBSet(db, model);
if (model.ID == 0)
{
CallMethod(dbSet, "Add", new object[] { model });
}
else
{
CallMethod(dbSet, "Attach", new object[] { model });
db.Entry(model).State = EntityState.Modified;
}
if (model.GetType().IsSubclassOf(typeof(SH_SetBase)))
{
((SH_SetBase)model).LastUpdateTime = DateTime.Now;
((SH_SetBase)model).IsDelete = false;
}
else
{
((SH_LogBase)model).LogTime = DateTime.Now;
}
db.SaveChanges();
return true;
}
} public static bool Delete(SH_Base model)
{
using (ShopContext db = new ShopContext())
{
if (model.GetType().IsSubclassOf(typeof(SH_SetBase)))
{
((SH_SetBase)model).LastUpdateTime = DateTime.Now;
((SH_SetBase)model).IsDelete = true;
db.Entry(model).State = EntityState.Modified;
db.SaveChanges();
return true;
} object dbSet = GetDBSet(db, model);
CallMethod(dbSet, "Remove", new object[] { model });
db.Entry(model).State = EntityState.Modified;
db.SaveChanges();
return true;
}
} private static object GetDBSet(ShopContext db, SH_Base model)
{
string modelName = ObjectContext.GetObjectType(model.GetType()).Name;
modelName = modelName.Replace("SH_", "");
Type type = db.GetType();
PropertyInfo property = type.GetProperty(modelName);
object dbSet = property.GetValue(db);
return dbSet;
} private static object GetDBSet(ShopContext db, Type type)
{
type = ObjectContext.GetObjectType(type);
string modelName = type.Name;
modelName = modelName.Replace("SH_", "");
PropertyInfo property = db.GetType().GetProperty(modelName);
object dbSet = property.GetValue(db);
return dbSet;
} private static object CallMethod(object obj, string methodName, object[] parms)
{
Type type = obj.GetType();
MethodInfo methodInfo = type.GetMethod(methodName);
return methodInfo.Invoke(obj, parms);
}
}

  可以看到里面包含了对SH_SetBase的特殊处理,这个有必要解释一下,因为老大之前的设计是数据库表分为两类,一种是记录表(日志表),他们继承自SH_LogBase,一种是姑且说是对象表吧,他们继承自SH_SetBase,然后全部表继承自SH_Base表,为什么要这样设计呢,其中一个原因是对象表里的数据不能真删除,他们一般是有外键的,级联删除的话删除太多了,而且里面的数据也很重要,只能假删除,所以SH_SetBase得有是否删除IsDelete字段,假删除的话那部分数据是不会再取出来的,除了假删除应该还可以禁用,比如冻结账号,冻结后又可以解冻,这就需要是否启用字段IsEnable字段。

  SH_Base表:

    public class SH_Base
{
/// <summary>
/// 标识,自动增加
/// </summary>
[Key]
public long ID
{
get;
set;
} /// <summary>
/// 备注
/// </summary>
[Display(Name = "备注")]
public string Summary
{
get;
set;
}
}

  SH_LogBase表:

    public class SH_LogBase : SH_Base
{
private DateTime _logTime = DateTime.Now; /// <summary>
/// 记录时间,默认当前时间
/// </summary>
[Display(Name = "记录时间")]
public DateTime LogTime
{
get { return _logTime; }
set { _logTime = value; }
}
}

  SH_SetBase表:

    public class SH_SetBase : SH_Base
{
/// <summary>
/// 是否删除,默认未删除
/// </summary>
[Display(Name = "是否删除")]
public bool IsDelete
{
get;
set;
} private bool _isEnable = true; /// <summary>
/// 是否启用,默认为启用
/// </summary>
[Display(Name = "是否启用")]
public bool IsEnable
{
get { return _isEnable; }
set { _isEnable = value; }
} private DateTime _lastUpdateTime = DateTime.Now; /// <summary>
/// 最后更新时间,默认当前时间
/// </summary>
[Display(Name = "最后更新时间")]
public DateTime LastUpdateTime
{
get { return _lastUpdateTime; }
set { _lastUpdateTime = value; }
}
}

  可我发觉DalHelper太臃肿了,而且里面用到了反射,我一直避免用反射,觉得那货效率比较低。后来看了C#线程内唯一的单例用法。把DalHelper拆分成两个BaseDal和SetBaseDal类,他们继承自IBaseDal类,里面的数据库采用线程内单例模式:

    public class DbContextFactory
{
public static ShopContext GetCurrentDbContext()
{
var db = (ShopContext)CallContext.GetData("ShopContext");
if (db != null) return db;
db = new ShopContext();
CallContext.SetData("ShopContext", db);
return db;
}
}

  或许有些同志会好奇线程内单例模式有什么好处或者什么用,我这里简单做个测试:

        public static ShopContext GetCurrentDbContext()
{
//单例模式:保证线程实例唯一
var db = (ShopContext)CallContext.GetData("ShopContext");
if (db != null)
{
File.AppendAllText("E:\\ShopDb.txt", Thread.CurrentThread.ManagedThreadId + "旧");
return db;
}
File.AppendAllText("E:\\ShopDb.txt", Environment.NewLine + Thread.CurrentThread.ManagedThreadId + "新");
db = new ShopContext();
CallContext.SetData("ShopContext", db);
return db;
}

  然后运行网站程序,随便乱点打开ShopDb.txt一看

可以看出我每点一次网页链接,控制器的Action接收到请求后就会新建一个线程来处理这次请求,由于我在该线程内一直没有另开线程,所以看到的生成的文件内每次请求就会产生一个新的ShopContext,在单次网页请求内用的都是同一个ShopContext的,这样你可能会说有问题呀,单次网页请求共用一个ShopContext,要是某次数据库请求太耗时,难道后续的操作要一直等待吗,这个问题确实存在,解决的办法就是数据库请求采用异步请求,单个线程共用ShopContext有个好处就是单次请求内只需新建一次ShopContext,不用老在内存中新建这个对象,这样的话可能你会说像线程池一样,搞个ShopContext池不是更好吗,线程要的时候去池中取一个ShopContext出来,不用的时候归还给池,这样ShopContext在内存中新建销毁的次数就可以达到最少次数了,这个我就不研究下去了。

  接口IBaseDal类:

    interface IBaseDal<T>
{
T Find(long id);
T First(Expression<Func<T, bool>> predicate);
T Add(T entity);
bool Update(T entity);
bool Delete(long id);
bool Delete(T entity);
bool Delete(IEnumerable<T> entities);
bool Exist(Expression<Func<T, bool>> predicate);
int Count(Expression<Func<T, bool>> predicate);
int Sum(Expression<Func<T, bool>> predicate, Expression<Func<T, int>> selector);
decimal Sum(Expression<Func<T, bool>> predicate, Expression<Func<T, decimal>> selector);
IQueryable<T> LoadEntities();
IQueryable<T> LoadEntities(Expression<Func<T, bool>> predicate);
IQueryable<T> LoadPageEntities<TS>(PageContent page, Expression<Func<T, bool>> predicate,
Expression<Func<T, TS>> keySelector, bool isAsc);
}

  日志类使用的BaseDal类:

    public class BaseDal<T> : IBaseDal<T> where T : class , new()
{
public static ShopContext Db
{
get
{
return DbContextFactory.GetCurrentDbContext();
}
} public virtual T Find(long id)
{
return Db.Set<T>().Find(id);
} public virtual T First(Expression<Func<T, bool>> predicate)
{
return Db.Set<T>().FirstOrDefault(predicate);
} public virtual T Add(T entity)
{
Db.Set<T>().Add(entity);
return entity;
} public virtual bool Update(T entity)
{
Db.Entry(entity).State = EntityState.Modified;
return true;
} public virtual bool Delete(long id)
{
return Delete(Find(id));
} public virtual bool Delete(T entity)
{
Db.Set<T>().Remove(entity);
return true;
} public virtual bool Delete(IEnumerable<T> entities)
{
Db.Set<T>().RemoveRange(entities);
return true;
} public virtual bool Exist(Expression<Func<T, bool>> predicate)
{
return Db.Set<T>().Any(predicate);
} public virtual int Count(Expression<Func<T, bool>> predicate)
{
return Db.Set<T>().Count(predicate);
} public virtual int Sum(Expression<Func<T, bool>> predicate, Expression<Func<T, int>> selector)
{
try
{
return Db.Set<T>().Where(predicate).Sum(selector);
}
catch
{
return ;
}
} public virtual decimal Sum(Expression<Func<T, bool>> predicate, Expression<Func<T, decimal>> selector)
{
try
{
return Db.Set<T>().Where(predicate).Sum(selector);
}
catch
{
return ;
}
} public virtual IQueryable<T> LoadEntities()
{
return Db.Set<T>().AsQueryable();
} public virtual IQueryable<T> LoadEntities(Expression<Func<T, bool>> predicate)
{
return Db.Set<T>().Where(predicate);
} public virtual IQueryable<T> LoadPageEntities<TS>(PageContent page, Expression<Func<T, bool>> predicate, Expression<Func<T, TS>> keySelector, bool isAsc)
{
page.TotalItems = Count(predicate);
var lst = Db.Set<T>().Where(predicate);
lst = isAsc ? lst.OrderBy(keySelector) : lst.OrderByDescending(keySelector);
return lst.Skip(page.PageSize * (page.PageIndex - ))
.Take(page.PageSize);
}
}

  对象类使用的SetBaseDal类:

    public class SetBaseDal<T> : IBaseDal<T> where T : SH_SetBase, new()
{
public static ShopContext Db
{
get
{
return DbContextFactory.GetCurrentDbContext();
}
} public virtual T Find(long id)
{
var t = Db.Set<T>().Find(id);
return t.IsDelete ? null : t;
} public virtual T First(Expression<Func<T, bool>> predicate)
{
return Db.Set<T>().Where(o => !o.IsDelete).FirstOrDefault(predicate);
} public virtual T Add(T entity)
{
Db.Set<T>().Add(entity);
return entity;
} public virtual bool Update(T entity)
{
entity.LastUpdateTime = DateTime.Now;
Db.Entry(entity).State = EntityState.Modified;
return true;
} public virtual bool Delete(long id)
{
return Delete(Find(id));
} public virtual bool Delete(T entity)
{
entity.IsDelete = true;
entity.LastUpdateTime = DateTime.Now;
Db.Entry(entity).State = EntityState.Modified;
return true;
} public virtual bool Delete(IEnumerable<T> entities)
{
foreach (var entity in entities)
{
Delete(entity);
}
return true;
} public virtual bool Exist(Expression<Func<T, bool>> predicate)
{
return Db.Set<T>().Where(o => !o.IsDelete).Any(predicate);
} public virtual int Count(Expression<Func<T, bool>> predicate)
{
return Db.Set<T>().Where(o => !o.IsDelete).Count(predicate);
} public virtual int Sum(Expression<Func<T, bool>> predicate, Expression<Func<T, int>> selector)
{
try
{
return Db.Set<T>().Where(predicate).Where(o => !o.IsDelete).Sum(selector);
}
catch
{
return ;
}
} public virtual decimal Sum(Expression<Func<T, bool>> predicate, Expression<Func<T, decimal>> selector)
{
try
{
return Db.Set<T>().Where(predicate).Where(o => !o.IsDelete).Sum(selector);
}
catch
{
return ;
}
} public virtual IQueryable<T> LoadEntities()
{
return Db.Set<T>().Where(o => !o.IsDelete);
} public virtual IQueryable<T> LoadEntities(Expression<Func<T, bool>> predicate)
{
return Db.Set<T>().Where(predicate).Where(o => !o.IsDelete);
} public virtual IQueryable<T> LoadPageEntities<TS>(PageContent page, Expression<Func<T, bool>> predicate, Expression<Func<T, TS>> keySelector, bool isAsc)
{
page.TotalItems = Count(predicate);
var lst = Db.Set<T>()
.Where(predicate)
.Where(o => !o.IsDelete);
lst = isAsc ? lst.OrderBy(keySelector) : lst.OrderByDescending(keySelector);
return lst.Skip(page.PageSize * (page.PageIndex - ))
.Take(page.PageSize);
}
}

  里面还有个PageContent类:

    public class PageContent
{
public int PageIndex { get; set; } public int PageSize { get; set; } public int TotalItems { get; set; } public int TotalPages
{
get
{
if (PageSize == ) return ;
return (TotalItems + PageSize - )/PageSize;
}
}
}

  可以看出BaseDal和SetBaseDal之间最大的区别就是BaseDal删除是真删除,SetBaseDal不能真删除,调用删除方法自动执行假删除,而且SetBaseDal获取数据等所有方法都把假删除的数据排除掉了。可能你会问既然假删除的数据都被排除掉了,那他们还有存在的必要吗,当然有必要了,因为除了用户看这些数据,管理人员是可以直接去数据库看的,那就能看到那些被假删除的数据了。

  写好这BaseDal和SetBaseDal类之后,BLL的类就可以继承自这两个类或者不继承,在类里使用者两个类,设计理念我不在行,貌似不建议直接继承Dal的通用类,而是在BLL定义一个接口,然后实现每个表的该接口,并在该类里引用Dal里的通用类,不过我觉得怎么方便就怎么用吧,何必一定要符合设计理念呢。还有贫血模型也是,按照面向对象理念是不能设计为贫血模型的,因为一个对象必须是完整的,里面的属性就像一个对象的血肉肢体,而里面的方法就像一个对象能够进行的活动,缺少了方法的实体类就像是尸体类,光有肢体不能动,可我还是那句话,怎么方便就怎么用吧,为何一定要面向对象呢,而且我认为光有属性也有好处,当我只需要该对象来传值的时候其实是不需要该对象的行为的,这样的话贫血模型加载到内存中占用的内存就少了些了。当然,这只是我的胡言乱语,大神请直接忽视。。。

通用EF框架的更多相关文章

  1. EF框架step by step(7)—Code First DataAnnotations(1)

    Data annotation特性是在.NET 3.5中引进的,给ASP.NET web应用中的类提供了一种添加验证的方式.Code First允许你使用代码来建立实体框架模型,同时允许用Data a ...

  2. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(20)-多条件模糊查询和回收站还原的实现

    原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(20)-多条件模糊查询和回收站还原的实现 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架 ...

  3. ASP.NET MVC+EF框架+EasyUI实现权限管理(附源码)

    前言:时间很快,已经快到春节的时间了,这段时间由于生病,博客基本没更新,所以今天写一下我们做的一个项目吧,是对权限的基本操作的操作,代码也就不怎么说了,直接上传源码和图片展示,下面我们直接进入主题介绍 ...

  4. EF框架之——Code First以及踩过的这些“坑”

    传送门 Code First使用步骤 Code First报错和解决办法 以前在上海做了一段时间的Asp.net,基本用的都是.net自带的EF框架连接数据库,不过都是用的Model First,最近 ...

  5. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(24)-权限组的设计和实现(附源码)(终结)

    ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    (2):数据库访问层的设计Demo    (3):面向接口编程   (4 ):业务逻辑层的封装    ...

  6. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(23)-设置角色遗留问题和为权限设置角色以及EasyUI Tabs的使用

    ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    (2):数据库访问层的设计Demo    (3):面向接口编程   (4 ):业务逻辑层的封装    ...

  7. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(22)-为用户设置角色

    ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    (2):数据库访问层的设计Demo    (3):面向接口编程   (4 ):业务逻辑层的封装    ...

  8. EF框架的三种工作方式

    EF框架step by step(1)—Database-First EF框架step by step(2)—Model-First EF框架step by step(3)—Code-First 通过 ...

  9. C# CodeFirst(EF框架)代码优先创建数据库

    namespace WebEF.Model{ public class ModelContext:DbContext //继承DBcontext 来自EF框架 { public ModelContex ...

随机推荐

  1. 总结移动安全的测试点及详解allowbackup漏洞

    一.移动应用APP可能面临以下威胁: 木马--二次打包, 病毒--账号窃取, 篡改--资源篡改, 破解--广告植入, 钓鱼--信息劫持  二.移动终端APP安全评估的7个方向: 通信安全,敏感信息安全 ...

  2. RakNet基本教程

    官方网址:http://www.jenkinssoftware.com/raknet/manual/tutorialsample3.html Tutorial code sample 3 Remote ...

  3. CISCO VLAN ACL

    对于cisco VLAN ACL 首先得定义 standard ACL或 extented ACL用于抓取流量 注意这里的抓取流量不是最终的对流量的操作,而是决定什么样的流量用VLAN ACL 来处理 ...

  4. cnetos7.0 安装mysql

    CentOS 7的yum源中貌似没有正常安装mysql时的mysql-sever文件,需要去官网上下载 [root@localhost ~]# wget http://dev.mysql.com/ge ...

  5. Xcode最好用的日志打印方法

    一般打印日志都是用的系统自带的NSLog来打印的,假如项目做完了,要上线了,这些打印的日志就会很浪费性能,网上有很多的解决办法,我也是感觉网上的还是有点不方便,所以就自己又修改了一下,分享给大家. 网 ...

  6. vs使用

    1.控制dll是否生成到本地,如图,右击dll,选择属性,设置复制到本地为true即可

  7. Linux面试知识点总结

    1.Linux关机重启命令: 在linux命令中reboot是重新启动,shutdown -r now是立即停止然后重新启动,都说他们两个是一样的,其实是有一定的区别的.    shutdown命令可 ...

  8. Lua源码编译之CL编译器编译

    通过使用VC下的CL编译器,可方便地编译Lua源码,而无需构造工程并设置各种选项: 以下以源码Lua5.3.1版本为例,将通过CL编译选项直接编译源码,为方便编译将采用批处理脚本,脚本放置在Lua解压 ...

  9. 用 Blend 给Windows Phone 应用创建 示例数据

    前言  创建 示例数据(Sample Data) 是提高程序开发效率的一个很有效方法,有了它,我们调UI的时候就不必每次都运行应用,然后在手机上观看页面效果了,配合 “AlignmentGrid.pn ...

  10. mysql导出excel文件的几种方法

    方法一 用mysql的命令和shell select * into outfile './bestlovesky.xls' from bestlovesky where 1 order by id d ...