我希望为生产服务器创建一个数据库行到对象映射器。
我的目标是在一个位置填充数据库列名称,以及该对象的字段,以存储从数据库查询返回的单个行。
我打算稍后添加功能来自动获取表名和连接字符串。这样做的目的是集中所有与数据库相关的东西(自动跟踪列和查询字符串的命名,添加对返回结果的保护,错误记录等)。
我读了很多关于泛型集访问器的想法,以为我目前无法从中合成解决方案。
这是我想要实现的(非工作)骨架。欢迎所有评论,关于优化和更好的做法。
利用率:
/* get MediaInfo filled regarding CDbColumnFind criterias */
CEventReportingMediaInfo MediaInfo = DbQuery(1, new CDbColumnFind() { Name = "uid", Value = "2" });
这是Db-Mappable基类
public class DbMappableClass
{
/********************************************/
/* required fields for database information */
/********************************************/
public string TableName;
public IList TableColumns;
/********************************************/
/* generic object filling helper */
/********************************************/
public void ReadObject(DataRow FromRow)
{
foreach (CDbColumn Column in TableColumns)
{
TryParseGeneric(FromRow[Column.Name].ToString(), Column.Field);
}
}
/********************************************/
/* conversion helper */
/********************************************/
public static bool TryParseGeneric(string src, T value)
{
TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
try
{
value = (T)converter.ConvertFromString(src);
return true;
}
catch
{
value = default(T);
CSysLog.WriteEntry(SysLogLevel.WARNING, "failed to convert src ({0}) to type ({1}), use default value ({2})", src.ToString(), typeof(T), value);
return false;
}
}
/********************************************/
/* Db column type */
/********************************************/
public class CDbColumn
{
private readonly string name;
private readonly SqlDbType sqltype;
private readonly Type ctype;
public CDbColumn(string Name, SqlDbType SqlType, object Field)
{
this.name = Name;
this.sqltype = SqlType;
this.Field = Field;
this.ctype = Field.GetType();
}
public string Name { get { return name; } }
public SqlDbType SqlType { get { return sqltype; } }
public object Field { get; set; }
public Type CType { get { return ctype; } }
}
/********************************************/
/* Db Query type criterias */
/********************************************/
public class CDbColumnFind
{
public string Name;
public object Value;
}
/********************************************/
/* Generic Db Query */
/********************************************/
public static TReturnType DbQuery(int ExpectedCount, params CDbColumnFind[] Args) where TReturnType : DbMappableClass, new()
{
/* query database, obtain results in RowResults ... */
TReturnType ReturnResult = new TReturnType();
DataRow RowResults = TableResult.Rows[0];
ReturnResult.ReadObject(RowResults);
}
}
现在是db-mappable派生对象的自定义集中声明
/********************************************/
/* Event Reporting Media Table : Database */
/********************************************/
public class CEventReportingMediaInfo : DbMappableClass
{
/**********************************/
/** Member Declaration ***/
/**********************************/
public int Uid { get; set; }
public MediaType Type { get; set; }
public string IpAddr { get; set; }
public Int32 Port { get; set; }
public MediaStatus Status { get; set; }
public int Delay { get; set; }
/**********************************/
/** Database Informations ***/
/**********************************/
public CEventReportingMediaInfo()
{
TableName = "event_reporting_media_tbl";
TableColumns = new ReadOnlyCollection (new[] {
new CDbColumn ("uid" , SqlDbType.Int, Uid),
new CDbColumn ("media_type" , SqlDbType.TinyInt, Type),
new CDbColumn ("media_ip" , SqlDbType.VarChar, IpAddr),
new CDbColumn ("media_port" , SqlDbType.Int, Port),
new CDbColumn ("media_status" , SqlDbType.TinyInt, Status),
new CDbColumn ("media_delay" , SqlDbType.Int, Delay)
});
}
public enum MediaType
{
INVALID = 0,
SIP_GATEWAY = 1,
MODEM = 2
}
public enum MediaStatus
{
OFFLINE = 0,
ONLINE = 1
}
}
如何通过ReadObject()通常填充指定的字段(Uid,Type,IpAddr等)?我需要一个等同于指向成员的指针...我也读过关于反射但我不确定效率并且不理解100%如何实现它。
注意:我宁愿不使用完整的ORM解决方案 - 我的理解是它不是一个长期的解决方案(对于未来的实施,支持等不太灵活 - 更容易但不是真正的企业级)。我希望保持对db映射层的控制,同时减少生产服务器上未来开发中出现的毛刺。
你们对这个实现有什么看法,以及实现目标的最佳方法是什么?
感谢您的时间,并致以最诚挚的问候,
睡眠
答案 0 :(得分:1)
你的猜测是正确的:你将不得不使用反射。
(一位已经完成DAL框架分享的人的一些建议。
DbMappableClass
)。它打破了设计,打破了分层,打破了简洁。)