解决方案 »
- 跪求C#获取MSN联系人列表!以及hotmail
- 所有数据类型都是从 object 派生出来的,可以说 int 型也是类吗?
- 谁能告诉我C#中的Socket的BeginReceive内部是如何异步的?
- using System.Linq命名空间无法引用!!!
- 如何让该语句隔三秒执行一次?
- 如何固定页面字体大小,使其对用<fond>标签定义的文字也有效?
- 简单问题
- 一个非常浪费时间的数据库操作,如何写个可以自动更新界面的等待窗体?
- 窗口第一次加载太慢是什么原因呀?
- question about :BinaryReader.ReadChars
- C# 怎么连接数据库?
- 关于C# Socket.BeginReceiveFrom的几个问题
ProductInfo.Save和OrderInfo.Save
不就得了
不同的实体类,里面属性数量,属性名称,属性类型,都不一样,你要做个通用的save,还要考虑之后可能会出现的,现在未定义的实体类,你觉得现实么?
那load又该怎么办,load之前你不知道要load的是什么,能load出来?
/// 数据辅助类
/// </summary>
[Serializable]
public class MonitorParam
{ public string processPath; /// <summary>
/// 监测类型
///
/// </summary>
public int monitorType;
} private readonly string fileName = "process.dat"; /// <summary>
/// 保存当前进程列表到文件
/// </summary>
/// <param name="filename"></param>
public bool SaveProcessToFile(Dictionary<string, MonitorParam> processlist)
{
bool flag = false;
try
{
if (File.Exists(fileName))
{
File.Delete(fileName);
}
string xmlpath = AppDomain.CurrentDomain.BaseDirectory;
using (FileStream writer = new FileStream(xmlpath + @"\" + fileName, FileMode.OpenOrCreate))
{
BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(writer, processlist);
}
flag = true;
}
catch (Exception ex)
{
}
return flag;
}
/// <summary>
/// 读取本地文件中的进程队列
/// </summary>
/// <param name="filename"></param>
/// <returns></returns>
public Dictionary<string, MonitorParam> GetProcessFromFile()
{
Dictionary<string, MonitorParam> result = new Dictionary<string, MonitorParam>();
try
{ string processPath = AppDomain.CurrentDomain.BaseDirectory;
string filePath = Path.Combine(processPath, fileName);
if (File.Exists(filePath))
{
using (FileStream reader = new FileStream(filePath, FileMode.Open))
{
BinaryFormatter formatter = new BinaryFormatter();
result = (Dictionary<string, MonitorParam>)formatter.Deserialize(reader); }
}
}
catch (Exception ex)
{
}
return result; }
如何保存任意实体,就好像在问:如何打造一把万能锁钥1.如楼上所说的,每个实体类中,自定义save方法,通过实体.save()调用。
2.还是要每个实体类中,自定义save方法。但是:使用简单工厂模式,在工厂中进行判断(用switch语句枚举判断。可以使用反射机制加速效率),并在工厂中实现实体.save()调用。客户端只需要
Factory.Save(ProductInfo);
Factory.Save(OrderInf9);
就可以保存相应的实体。
以此隐藏save方法的细节。
public class AnyClass
{
public object AnyData = null;
} /**/
/// <summary>
/// 将一个object对象序列化,返回一个byte[]
/// </summary>
/// <param name="obj">能序列化的对象</param>
/// <returns></returns>
public static byte[] ObjectToBytes(object obj)
{
using (MemoryStream ms = new MemoryStream())
{
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
return ms.GetBuffer();
}
} /**/
/// <summary>
/// 将一个序列化后的byte[]数组还原
/// </summary>
/// <param name="Bytes"></param>
/// <returns></returns>
public static object BytesToObject(byte[] Bytes)
{
using (MemoryStream ms = new MemoryStream(Bytes))
{
IFormatter formatter = new BinaryFormatter();
return formatter.Deserialize(ms);
}
} public static void save(string Path, object SenderFile)
{
byte[] tempdata = ObjectToBytes(SenderFile);
File.WriteAllBytes(Path, tempdata);
} public static object inputfile(string Path)
{
byte[] tempdata = File.ReadAllBytes(Path);
return BytesToObject(tempdata);
}
类似这种?
{
public void Save<T>(T obj)
{
......
}
........
}这其实就是 ORM!或者看看你的 vs 里的 EF 工具也是如此。(只不过 EF 接口不如自己开发的 ORM 更好用而已)
至少有两种写法。一种是可以采用基于反射的做法。例如public void Save<T>(T obj)
{
FieldInfo[] fs = typeof(T).GetFields();
Dictionary<string, object> dic = new Dictionary<string, object>();
foreach (var f in fs)
dic.Add(f.Name, f.GetValue(obj));
找到 fs 中名为 ID 的属性作为主键_保存数据到数据库(dic);
}这里,实际上仅需要执行一次 GetFields ,然后把 fs 就缓存起来。而不需要每一次对同一类型对象执行Save时都反射一次。另外一种,就像 EF 一样,在vs上开发一个插件,预先自动对用户代码进行语法分析并且产生"针对每一个类型的单独的Save方法代码“,例如假设生成的隐藏代码的方法(委托)放在一个 SaveMethods<string, Action<object>> 集合中,那么Save方法就可以写为public void Save<T>(T obj)
{
string name = typeof(T).FullName;
SaveMethods[name](obj);
}
{
....
}它支持使用者使用标准的LINQ语法来编写查询语句(你的这个Query<T>函数会自动产生数据库原生查询语句并延迟查询),你也可能需要考虑是否支持多态的问题。比如说用户写var result = from x in Person
where x.City == "成都"
select x;这时候你需要考虑假设某个 Person 实例当初 Save(obj) 的时候其实是作为 Pregnant 实体保存的,那么此时是否应该在Person集合中包括一个 Pregnant 实体呢?
如何保存任意实体,就好像在问:如何打造一把万能锁钥1.如楼上所说的,每个实体类中,自定义save方法,通过实体.save()调用。
2.还是要每个实体类中,自定义save方法。但是:使用简单工厂模式,在工厂中进行判断(用switch语句枚举判断。可以使用反射机制加速效率),并在工厂中实现实体.save()调用。客户端只需要
Factory.Save(ProductInfo);
Factory.Save(OrderInf9);
就可以保存相应的实体。
以此隐藏save方法的细节。这个好,有借鉴的代码不?
这个好,有借鉴的代码不?这是设计模式入门的基础知识,其实效率并不高。
《大话设计模式》//简单运算工厂类
public class OperationFactory {
public static Operation createOperate(String operate)
{
Operation oper=null;
switch(operate)
{
case "+":
oper=new OperationAdd();
break;
case "-":
oper=new OperationSub();
break;
case "*":
oper=new OperationMul();
break;
case "/":
oper=new OperationDiv();
break;
}
return oper;
}
}
从核心代码可以看到,里面只是简单的switch遍历,效率不高,使用反射可以改进。
请教大神,评价下这样的设计,这是基于三层架构开发的,定义了实体类、实体的抽象接口类、实体的逻辑处理类;扫下盲哈:namespace GIS.Model
{
/// <summary>
/// Sys_Department:实体类(属性说明自动提取数据库字段的描述信息)
/// </summary>
[Serializable]
public partial class Sys_Department
{
public Sys_Department()
{}
#region Model
private int _dept_id;
private string _up_dept_id;
private string _dept_name;
private string _dept_desc;
private decimal? _sort;
/// <summary>
///
/// </summary>
public int DEPT_ID
{
set{ _dept_id=value;}
get{return _dept_id;}
}
/// <summary>
///
/// </summary>
public string UP_DEPT_ID
{
set{ _up_dept_id=value;}
get{return _up_dept_id;}
}
/// <summary>
///
/// </summary>
public string DEPT_NAME
{
set{ _dept_name=value;}
get{return _dept_name;}
}
/// <summary>
///
/// </summary>
public string DEPT_DESC
{
set{ _dept_desc=value;}
get{return _dept_desc;}
}
/// <summary>
///
/// </summary>
public decimal? SORT
{
set{ _sort=value;}
get{return _sort;}
}
#endregion Model }
}
using System;
using System.Data;
namespace GIS.IDAL
{
/// <summary>
/// 接口层Sys_Department
/// </summary>
public interface ISys_Department
{
#region 成员方法
/// <summary>
/// 是否存在该记录
/// </summary>
bool Exists(string DEPT_ID);
/// <summary>
/// 增加一条数据
/// </summary>
bool Add(GZPI.GZDX.GISPortal.Model.Sys_Department model);
/// <summary>
/// 更新一条数据
/// </summary>
bool Update(GZPI.GZDX.GISPortal.Model.Sys_Department model);
/// <summary>
/// 删除一条数据
/// </summary>
bool Delete(string DEPT_ID);
bool DeleteList(string DEPT_IDlist );
/// <summary>
/// 得到一个对象实体
/// </summary>
GZPI.GZDX.GISPortal.Model.Sys_Department GetModel(string DEPT_ID);
/// <summary>
/// 获得数据列表
/// </summary>
DataSet GetList(string strWhere);
/// <summary>
/// 根据分页获得数据列表
/// </summary>
//DataSet GetList(int PageSize,int PageIndex,string strWhere);
#endregion 成员方法
}
}=
namespace GIS.BLL
{
/// <summary>
/// Sys_Department
/// </summary>
public partial class Sys_Department
{
private readonly ISys_Department dal=DataAccess.CreateSys_Department();
public Sys_Department()
{}
#region Method
/// <summary>
/// 是否存在该记录
/// </summary>
public bool Exists(string DEPT_ID)
{
return dal.Exists(DEPT_ID);
} /// <summary>
/// 增加一条数据
/// </summary>
public bool Add(GIS.Model.Sys_Department model)
{
return dal.Add(model);
} /// <summary>
/// 更新一条数据
/// </summary>
public bool Update(GIS.Model.Sys_Department model)
{
return dal.Update(model);
} .......省略.....
#endregion Method
}
}
请教大神,评价下这样的设计,这是基于三层架构开发的,定义了实体类、实体的抽象接口类、实体的逻辑处理类;扫下盲哈:namespace GIS.Model
{
/// <summary>
/// Sys_Department:实体类(属性说明自动提取数据库字段的描述信息)
/// </summary>
[Serializable]
public partial class Sys_Department
{
public Sys_Department()
{}
#region Model
private int _dept_id;
private string _up_dept_id;
private string _dept_name;
private string _dept_desc;
private decimal? _sort;
/// <summary>
///
/// </summary>
public int DEPT_ID
{
set{ _dept_id=value;}
get{return _dept_id;}
}
/// <summary>
///
/// </summary>
public string UP_DEPT_ID
{
set{ _up_dept_id=value;}
get{return _up_dept_id;}
}
/// <summary>
///
/// </summary>
public string DEPT_NAME
{
set{ _dept_name=value;}
get{return _dept_name;}
}
/// <summary>
///
/// </summary>
public string DEPT_DESC
{
set{ _dept_desc=value;}
get{return _dept_desc;}
}
/// <summary>
///
/// </summary>
public decimal? SORT
{
set{ _sort=value;}
get{return _sort;}
}
#endregion Model }
}
using System;
using System.Data;
namespace GIS.IDAL
{
/// <summary>
/// 接口层Sys_Department
/// </summary>
public interface ISys_Department
{
#region 成员方法
/// <summary>
/// 是否存在该记录
/// </summary>
bool Exists(string DEPT_ID);
/// <summary>
/// 增加一条数据
/// </summary>
bool Add(GZPI.GZDX.GISPortal.Model.Sys_Department model);
/// <summary>
/// 更新一条数据
/// </summary>
bool Update(GZPI.GZDX.GISPortal.Model.Sys_Department model);
/// <summary>
/// 删除一条数据
/// </summary>
bool Delete(string DEPT_ID);
bool DeleteList(string DEPT_IDlist );
/// <summary>
/// 得到一个对象实体
/// </summary>
GZPI.GZDX.GISPortal.Model.Sys_Department GetModel(string DEPT_ID);
/// <summary>
/// 获得数据列表
/// </summary>
DataSet GetList(string strWhere);
/// <summary>
/// 根据分页获得数据列表
/// </summary>
//DataSet GetList(int PageSize,int PageIndex,string strWhere);
#endregion 成员方法
}
}=
namespace GIS.BLL
{
/// <summary>
/// Sys_Department
/// </summary>
public partial class Sys_Department
{
private readonly ISys_Department dal=DataAccess.CreateSys_Department();
public Sys_Department()
{}
#region Method
/// <summary>
/// 是否存在该记录
/// </summary>
public bool Exists(string DEPT_ID)
{
return dal.Exists(DEPT_ID);
} /// <summary>
/// 增加一条数据
/// </summary>
public bool Add(GIS.Model.Sys_Department model)
{
return dal.Add(model);
} /// <summary>
/// 更新一条数据
/// </summary>
public bool Update(GIS.Model.Sys_Department model)
{
return dal.Update(model);
} .......省略.....
#endregion Method
}
}一个好的 DAL 框架应该跟具体某个业务实体没有什么关系。你在 DAL 里边纠结什么 Department 等等,那么你的 DAL 一定是一大堆、比100年前老太太的裹脚布还要长、还要味道不好的代码。一个 DAL 框架的代码应该专业,针对数据库操作。有些人从微软10几年前坑爹的 PetShop 中学来的所谓 DAL,它纯粹是重复 BLL 层的东西。在 DAL 里围绕每一个业务对象去手工编写一堆千篇一律的代码,这充其量只应该是代码生成器来做的。更好的方法是连代码生成器都不要。如果手工写你这些代码,我觉得实在是还不如不搞编程这种低级工作。
{
db.Save(obj1);
foreach(var x in from a in db.Query<Person>()
where a.City == "成都"
select a)
{
x.City = "新成都";
db.Save(x);
}
db.Commit();
}类似于这样,一个 DAL 可以将“未知类型的”对象保存到对应的数据库中,并且可以查询,而不需要像 EF 那样需要繁琐的什么“视图定义、重建”等等一大堆复杂配置操作,那么就更方便。总之,DAL就是数据库驱动。只不过它跟 ADO.NET 的区别在于是否直接处理面向对象实体。而 PetShop 式的所谓 DAL,是画蛇添足,繁琐地增加没有技术含量的层次,很难说那种 DAL 到底有什么用。因为它不过是对 BLL 进行繁琐封装,而没有实现真正自成一体的、在你创建业务实体之前就创建了的通用 DAL 框架。
请教大神,评价下这样的设计,这是基于三层架构开发的,定义了实体类、实体的抽象接口类、实体的逻辑处理类;扫下盲哈:namespace GIS.Model
{
/// <summary>
/// Sys_Department:实体类(属性说明自动提取数据库字段的描述信息)
/// </summary>
[Serializable]
public partial class Sys_Department
{
public Sys_Department()
{}
#region Model
private int _dept_id;
private string _up_dept_id;
private string _dept_name;
private string _dept_desc;
private decimal? _sort;
/// <summary>
///
/// </summary>
public int DEPT_ID
{
set{ _dept_id=value;}
get{return _dept_id;}
}
/// <summary>
///
/// </summary>
public string UP_DEPT_ID
{
set{ _up_dept_id=value;}
get{return _up_dept_id;}
}
/// <summary>
///
/// </summary>
public string DEPT_NAME
{
set{ _dept_name=value;}
get{return _dept_name;}
}
/// <summary>
///
/// </summary>
public string DEPT_DESC
{
set{ _dept_desc=value;}
get{return _dept_desc;}
}
/// <summary>
///
/// </summary>
public decimal? SORT
{
set{ _sort=value;}
get{return _sort;}
}
#endregion Model }
}
using System;
using System.Data;
namespace GIS.IDAL
{
/// <summary>
/// 接口层Sys_Department
/// </summary>
public interface ISys_Department
{
#region 成员方法
/// <summary>
/// 是否存在该记录
/// </summary>
bool Exists(string DEPT_ID);
/// <summary>
/// 增加一条数据
/// </summary>
bool Add(GZPI.GZDX.GISPortal.Model.Sys_Department model);
/// <summary>
/// 更新一条数据
/// </summary>
bool Update(GZPI.GZDX.GISPortal.Model.Sys_Department model);
/// <summary>
/// 删除一条数据
/// </summary>
bool Delete(string DEPT_ID);
bool DeleteList(string DEPT_IDlist );
/// <summary>
/// 得到一个对象实体
/// </summary>
GZPI.GZDX.GISPortal.Model.Sys_Department GetModel(string DEPT_ID);
/// <summary>
/// 获得数据列表
/// </summary>
DataSet GetList(string strWhere);
/// <summary>
/// 根据分页获得数据列表
/// </summary>
//DataSet GetList(int PageSize,int PageIndex,string strWhere);
#endregion 成员方法
}
}=
namespace GIS.BLL
{
/// <summary>
/// Sys_Department
/// </summary>
public partial class Sys_Department
{
private readonly ISys_Department dal=DataAccess.CreateSys_Department();
public Sys_Department()
{}
#region Method
/// <summary>
/// 是否存在该记录
/// </summary>
public bool Exists(string DEPT_ID)
{
return dal.Exists(DEPT_ID);
} /// <summary>
/// 增加一条数据
/// </summary>
public bool Add(GIS.Model.Sys_Department model)
{
return dal.Add(model);
} /// <summary>
/// 更新一条数据
/// </summary>
public bool Update(GIS.Model.Sys_Department model)
{
return dal.Update(model);
} .......省略.....
#endregion Method
}
}我觉得结构还不错。从代码实现上说,使用提供基本 CRUD 的支持类模版的基类处理基本的数据存取操作可以减少大量的代码,我觉得可以使用 NHibernate 这是更成熟的产品。从设计模式上来讲,模型,基础架构和业务相互分离是很不错的,概念理解也是正确的,我觉得还需要 DataTransferObject 和一些 ObjectTranslator,把业务模型和数据模型区分开可以更好的解耦合
感谢大神指点!!
这样的DAL设计是微软很早之前提出的,对于新人来说,那个petshop的例子的确很有学习意义。我个人觉得,虽然这种设计虽然有点冗余过时,而且有很多更好更高效率简洁的架构可以使用,但是我们应该理解这种设计的优点和缺点,这样我们更能明白ORM系统的精华所在。不断学习进步,方能走得更远!