在坐一个对象化存储时,又遇到一个够郁闷的问题。所使用的一个组件,在往数据库存对象时,必须要指定对象的主键。而且这个主键是guid ,nvarchar(50)类型。
一般新增数据会先newid一个guid.可是,遇到了一个数据库,数据库主键采用的类型是Int 自增型。而且设置了IDENTITY标示。
原本我想改动一下数据库表类型,去掉字段的IDENTITY。
SET IDENTITY_INSERT products2 ON 让可以显示的插入id.可不符合业务,也会增加逻辑复杂度;
可我那组件在往数据库插入新的记录时,一定会显示的带上那个identity的字段。于是老是报错,又不提供这样的方法。。根本没法往下进行的节奏;
我又不是这个组件的提供者,有没代码。幸好老子聪明,奶奶的,一不做二不休,反编译了这个组件,幸好这个组件没有加壳,轻松反编译出来了源码。于是顺利的改了源码,加上了我需要的function.
中间遇到一个问题,取对象某个指定属性,哦,请原谅我,我现在有点懒。直接上代码吧
public void StoreIdentityTable(T obj) { using (SqlConnection connection = SqlHelper.GetSqlConnection(this.GetConnectionString())) { SqlTransaction trans = connection.BeginTransaction(); try { this.Delete(obj, trans); List<SqlParameter> list = new List<SqlParameter>(); foreach (PropertyInfo info in this.Attributes) { object[] objAttrs = info.GetCustomAttributes(typeof(IDAttribute), true); //如果有这个[ID]属性,那么不用在sql中加入这个主键字段,因为这个是在数据库自增的 if (objAttrs.Length > 0) { continue; } SqlParameter item = new SqlParameter("@" + info.Name, this.GetDbType(info)); item.Value = this.GetValueByType(info, obj); list.Add(item); } SqlHelper.ExecuteNonQuery(trans, CommandType.Text, this.SQL_INSERTIDENTITY, list.ToArray()); trans.Commit(); } catch (Exception exception) { trans.Rollback(); throw exception; } } }
关键的就是那几句代码,再给个取<T>类型的类似的代码:
public class IBaseTable<T> : MarshalByRefObject { public string ID { // get the special attribute [IDAttribute] ;by cq get { if (String.IsNullOrEmpty(mID)) { foreach (PropertyInfo propInfo in typeof(T).GetProperties()) { object[] objAttrs = propInfo.GetCustomAttributes(typeof(IDAttribute), true); if (objAttrs.Length > 0) { mID = propInfo.Name; break; } } } return mID; } } }
这里我要使用的对象有一个这样的特性【ID】 (IDAttribute缩写)
public class Employee { /// <summary> /// 主键ID /// </summary> [ID] public string EmpID { get; set; } }