通用EF框架

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


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

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>> wherewhere 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>> wherewhere 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>> wherewhere 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>> wherewhere 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>> wherewhere 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 0;
            }
        }

        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 0;
            }
        }

        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 - 1))
                  .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 0;
            }
        }

        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 0;
            }
        }

        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 - 1))
                  .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 == 0) return 0;
                return (TotalItems + PageSize - 1)/PageSize;
            }
        }
    }

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

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

时间: 2024-10-08 02:41:07

通用EF框架的相关文章

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

Data annotation特性是在.NET 3.5中引进的,给ASP.NET web应用中的类提供了一种添加验证的方式.Code First允许你使用代码来建立实体框架模型,同时允许用Data annotation特性来配置类和属性的某些特性. 其实在前面的几篇文章中,有用到几个,在这一篇里,进行一次比较全面的介绍 Key EF框架要求每个实体必须有主键字段,他需要根据这个主键字段跟踪实体.CodeFirst方法在创建实体时,也必须指定主键字段,默认情况下属性被命名为ID.id或者[Clas

【.NET】EF框架之环境配置

我们的开发环境是VS2012,既然要使用EF做框架,必然要安装EntityFramework.这是EF框架的编程模型,微软官网可以下载,现在的版本是EF6.1.1.行动之前先安装一个插件,叫做NuGet PackageManager,它的作用就是为VS工程项目自动下载/安装/升级/配置/移除包. 方法如下: 插件安装完成后重启VS.然后新建一个C#项目. 然后再控制台输入下图红色框中的命令: 安装完成后,你会惊奇的发现: (1)多了一个文件. (2)App.Config内容多了一部分. <con

EF框架操作postgresql,实现WKT类型坐标的插入,查询,以及判断是否相交

1.组件配置 首先,要下载.NET for Postgresql的驱动,npgsql,EF6,以及EntityFramework6.Npgsql,版本号 3.1.1.0. 由于是mvc项目,所以,把相应的配置文件写在web.config里面,如下: 1 <configSections> 2 <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?L

ASP.NET MVC+EF框架+EasyUI实现权限管理系列

http://www.cnblogs.com/hanyinglong/archive/2013/03/22/2976478.html ASP.NET MVC+EF框架+EasyUI实现权限管理系列之开篇 前言:博客又有一段时间没有更新了,心里感觉这段时间空空的,好像什么都没有学下,所以就想写博客,所以就有了这个系列,这里当然也要感谢大家了,因这个 项目我已经上传了,得到了很多网友的评价,也有好多人发邮件给我说这个框架容易出现问题,不能访问,这也是支持我写这个系列的动力,我将这个项目写成一个 系列

【.NET】EF框架之三种模式

使用EF之前必须要对EF有个宏观的了解.学习任何一种技术都要像门卫一样问几个问题. 第一,它是谁? 第二,从哪里来? 第三,到哪里去? 默念一遍:不谋全局者,不足谋一域. 今天老师宏观给讲了一下EF的好处,抛出为什么要用EF的问题,我们的回答仅仅是概念和技术上的浅显的认识,老师的话我并未全部理解.先来整理一下自己所认识的EF吧. Entity Framework是ORMapping的一种具体实现,那ORMapping又是什么呢?ORM--ObjectRelation Mapping,即对象关系映

Unity3D通用UI框架

目标:编写一个简单通用UI框架用于管理页面和完成导航跳转最终的实现效果请拉到最下方查看 框架具体实现的功能和需求 加载,显示,隐藏,关闭页面,根据标示获得相应界面实例 提供界面显示隐藏动画接口 单独界面层级,Collider,背景管理 根据存储的导航信息完成界面导航 界面通用对话框管理(多类型Message Box) 便于进行需求和功能扩展(比如,在跳出页面之前添加逻辑处理等) 编写UI框架意义 打开,关闭,层级,页面跳转等管理问题集中化,将外部切换等逻辑交给UIManager处理 功能逻辑分散

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

namespace WebEF.Model{ public class ModelContext:DbContext //继承DBcontext 来自EF框架 { public ModelContext() : base("name=配置文件名") { //读取配置文件 /*配置文件的设置格式 <connectionStrings> <add name="配置文件名" connectionString="Data Source=(. .l

VS2012里面使用EF框架的增删改查和分页的方法

public class BaseRepository<T> where T : class    {        //实例化EF框架        DataModelContainer db = new DataModelContainer(); //添加        public T AddEntities(T entity)        {            db.Entry<T>(entity).State = EntityState.Added;        

.net EF框架 MySql实现实例

1.nuget中添加包EF和MySql.Data.Entity 2.config文件添加如下配置 1.配置entitframework节点(一般安装EF时自动添加) <entityFramework> <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> <parameters> <