最近对数据库的设计有些想法,貌似一般数据都有些通用字段
public interface IData
{
///
/// 数据ID标识
///
decimal ID { get; set; }
///
/// 更新时间
///
DateTime UpdateTime { get; set; }
///
/// 数据状态
///
int State { get; set; }
///
/// 创建时间
///
DateTime CreateTime { get; set; }
}
其中ID是自增长主键(SQL,Oracle环境可以是Sequence生成的ID)
UpdateTime是最后一次更新时间
CreateTime是创建时间
State是数据状态(本来的设想里没有,看了这个文章觉得状态字段实在太需要了。。)
类型如下:
数据库就这样了。。有什么用呢~?继续看。。
在这个的基础上,可以抽象出一个 IData 接口:
IData 接口
public interface IData
{
///
/// 数据ID标识
///
decimal ID { get; set; }
///
/// 更新时间
///
DateTime UpdateTime { get; set; }
///
/// 数据状态
///
int State { get; set; }
///
/// 创建时间
///
DateTime CreateTime { get; set; }
}
因为数据库的表字段跟IData属性成员是一致的,直接对Linq生成的实体类进行接口签名:
IData 接口签名
签名放在
一般没人用的Linq设计器cs文件里面了。。好处是方便跟着那个大坨的Linq文件走。。
这个文件右键dbml文件 -> 查看代码就出现了,默认是不出现的(因为很惹人讨厌,之前不小心弄出来了我都会把它删掉。。现在用上了。。)
当然了,上面的借口签名不是一个一个写出来的,直接CodeSmith很简单的就出来了
接下来,针对IData进行扩展:
数据对象扩展
///
/// 数据对象扩展
///
public static class DataExtension
{
///
/// 保存或更新
///
/// 要保存或更新的数据
/// 操作结果
public static bool SaveOrUpdate(this IData data)
{
bool success = false;
CIIDesignerDataContext db = new CIIDesignerDataContext();
// todo: save or update
if (data.ID < 1)
{
// todo: save
data.CreateTime = DateTime.Now;
data.UpdateTime = DateTime.Now;
db.GetTable(data.GetType()).InsertOnSubmit(data);
}
else
{
// todo: update
data.UpdateTime = DateTime.Now;
db.GetTable(data.GetType()).Attach(data);
db.SubmitChanges();
}
try
{
db.SubmitChanges();
success = true;
}
catch
{
success = false;
}
return success;
}
///
/// 删除数据
///
/// 要删除的数据
/// 操作结果
public static bool Delete(this IData data)
{
bool success = false;
CIIDesignerDataContext db = new CIIDesignerDataContext();
db.GetTable(data.GetType()).Attach(data);
db.GetTable(data.GetType()).DeleteOnSubmit(data);
try
{
db.SubmitChanges();
success = true;
}
catch (Exception)
{
success = false;
}
return success;
}
}
这样下来每个实体类可以直接增删改:(不知道这样用处大不大。。)
好了,现在我们的Linq实体类可以直接增删改,不用关心Linq的DataContext了,充血充的更厉害了……
但是查询的时候还是没办法彻底摆脱Linq的DataContext,再来~
不知道命名,就赶新潮也叫Repository(其实还是DataContext的范畴)
数据存储池
///
/// 数据存储池
///
///
public class Repository<T> where T : class, IData
{
CIIDesignerDataContext db = new CIIDesignerDataContext();
///
/// 创建数据对象
///
///
public T Create()
{
return (T)Activator.CreateInstance(typeof(T));
}
///
/// 根据主键获取数据
///
/// 主键ID
///
public T FindByID(decimal ID)
{
return db.GetTable<T>().FirstOrDefault(c => c.ID == ID);
}
///
/// 获取数据Query
///
///
public IQueryable<T> GetQuery()
{
return db.GetTable<T>().AsQueryable();
}
///
/// 查询数据
///
///
public IEnumerable<T> Query(Func<T,bool> Expression)
{
return db.GetTable<T>().Where(Expression);
}
///
/// 查询数据
///
/// 动态Linq查询
///
public IEnumerable<T> GetQuery(string dLinq)
{
// todo: DynamicLinq 查询
return null;
}
}
这样查询的功能全部被Repository接管了~(实现动态linq的Query方法后,可以直接用字符串查询)
基本上我们彻底离开DataContext了,用起来大概是这样:
TestClass
当然,对Repository还有还有很多事情可以继续做,让它成为一个真正的Repository
======
以上的做法,具体用处大不大还不知道
不过,不涉及到复杂跨表查询,是可以脱离Linq的DataContext了
而且使用中处理的实体类都是实现了IData接口的数据对象,辅以扩展方法,代码通用性得到很大提高
个人觉得还蛮有意义……