在网上看到大家都在学习linq,加上linq也出来几个月的时间了,我看大家对linq追逐挚爱,这并不是错,但是我觉得不明白其中的原理,linq中的基类是怎么实现的,那就对NET的了解有一点肤浅,可能是微软对NET最终目标“农民也会做软件”。当然我说了这一些就可以说我一对NET很了解,当然不是之所写这文章就是提醒自己与大家对NET技术不要追求表面,费话也不多说了。其实linq开发原理很早在NET中就有人用这一种原理了,据我知道Websharp就是类似linq的开发方式,而且是一个开源的框架,其实linq也没有什么就是通过反射与映射来组成SQL语句。现在我写一个简单的类似Linq基类代码
1.映射层代码:
(1).映射表
using System;
using System.Collections.Generic;
using System.Text;
namespace U5.CommonAttributes
{
/// <summary>
/// 映射表
/// </summary>
[AttributeUsage(System.AttributeTargets.Class)]
public class TablesAttribule : Attribute
{
/// <summary>
/// 构造表
/// </summary>
/// <param name="pTableName">表名</param>
public TablesAttribule(string pTableName)
{
this._TableName = pTableName;
}
private string _TableName=string.Empty;
public string TableName
{
get { return this._TableName; }
set { this._TableName = value; }
}
}
}
(2).映射表中的字段
using System;
using System.Collections.Generic;
using System.Text;
namespace U5.CommonAttributes
{
/// <summary>
/// 映射表字段
/// </summary>
[Serializable]
[AttributeUsage(AttributeTargets.All)]
public class ColumnsAttribute : Attribute
{
/// <summary>
/// 构造列
/// </summary>
/// <param name="pColumnName">列名</param>
/// <param name="pDbType">数据类型</param>
/// <param name="pValue">值</param>
/// <param name="pPrimaryKey">是否是主键</param>
public ColumnsAttribute(string pColumnName, System.Data.SqlDbType pDbType, bool pPrimaryKey)
{
this._ColumnName = pColumnName;
this._SqlDbType = pDbType;
this._PrimaryKey = pPrimaryKey; //用于更新与删除主键标志
}
private string _ColumnName = string.Empty;
/// <summary>
/// 列名
/// </summary>
public string ColumnName
{
get { return _ColumnName; }
set { _ColumnName = value; }
}
private System.Data.SqlDbType _SqlDbType = System.Data.SqlDbType.VarChar;
/// <summary>
/// 数据类型
/// </summary>
public System.Data.SqlDbType SqlDbType
{
get { return _SqlDbType; }
set { _SqlDbType = value; }
}
private bool _PrimaryKey = false;
/// <summary>
/// 是否是主键
/// </summary>
public bool PrimaryKey
{
get { return _PrimaryKey; }
set { _PrimaryKey = value; }
}
}
}
以上就是映射层的代码,下面写反射层的代码
2.反射层的代码
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using U5.CommonAttributes;
namespace U5.OperationRule
{
public class Factory
{
//组成insert SQL语句
public string Add(object o)
{
int i = 0;
Type t = o.GetType(); //取得当前实体
string Colums = string.Empty; //定义变量装载表列名
string ColumnsValue = string.Empty; //定义变量装载表列值
string StrSQL = string.Empty; //定义变量装载组成SQL句
Attribute TableNote = System.Attribute.GetCustomAttribute(t, typeof(TablesAttribule)); ///反射表
TablesAttribule Table = TableNote as TablesAttribule; //类型转换成可识别的表映射类
StrSQL = "Insert " + Table.TableName + "("; //一半insert SQL语句
System.Reflection.PropertyInfo[] pInfo = t.GetProperties(); //取得公共属性
SqlParameter[] Parameter = new SqlParameter[pInfo.Length]; //SqlParameter数组长度
foreach (System.Reflection.PropertyInfo Note in pInfo)
{
System.Attribute Columns = System.Attribute.GetCustomAttribute(Note, typeof(U5.CommonAttributes.ColumnsAttribute));//反射列
U5.CommonAttributes.ColumnsAttribute ColumnsNote = Columns as U5.CommonAttributes.ColumnsAttribute; //转换成可识别的表字段属性
ColumnsValue = t.GetProperty(Note.Name).GetValue(o, null).ToString(); //得到值
Colums += (Colums == "") ? "@" + ColumnsNote.ColumnName : ",@" + ColumnsNote.ColumnName;//组合SQL
Parameter[i] = new SqlParameter("@" + ColumnsNote.ColumnName.Replace("@", ""), ColumnsNote.SqlDbType);//组合 Parameter
Parameter[i].Value = ColumnsValue;
i++;
}
StrSQL = StrSQL + Colums.Replace("@", "") + ") Values(" + Colums + ")";//完整的insert语句
return StrSQL;
//现在得SQL语句与SqlParameter下面的代码就是向数据库写东西很简单了吧
}
public void Update(object o)
{
//...........
//和上面代码差不多
}
public void Query(object o)
{
//...........
//和ADD上面代码差不多
}
public void Delete(object o)
{
//...........
//和ADD上面代码差不多
}
}
}
///代码反射与映射的代码写我全写完了,现在可以测试一下了
1.业务实体
using System;
using System.Collections.Generic;
using System.Text;
using U5.CommonAttributes;
namespace U5.DataObjectSouled.Menu
{
[TablesAttribule("T_MENU")] //定义表名
public class MenuInfoDataEntity
{
private string _menu_id = string.Empty;
/// <summary>
/// 菜单ID
/// </summary>
[Columns("Menu_ID", System.Data.SqlDbType.VarChar,true)]//列名、列名类型、是否主键
public string Menu_ID
{
set { _menu_id = value; }
get { return _menu_id; }
}
private string _Menu_Name = string.Empty;
/// <summary>
/// 菜单名称
/// </summary>
[Columns("Menu_Name", System.Data.SqlDbType.VarChar, false)]//列名、列名类型、是否主键
public string Menu_Name
{
set { _Menu_Name = value; }
get { return _Menu_Name; }
}
private string _back_menu_id = string.Empty;
/// <summary>
/// 上一层菜单编码
/// </summary>
[Columns("Back_Menu_ID", System.Data.SqlDbType.VarChar, false)]//列名、列名类型、是否主键
public string Back_Menu_ID
{
set { _back_menu_id = value; }
get { return _back_menu_id; }
}
}
}
2.界面测试
protected void TEST_Click(object sender, System.EventArgs e)
{
U5.DataObjectSouled.Menu.MenuInfoDataEntity menu=new U5.DataObjectSouled.Menu.MenuInfoDataEntity();
menu.Menu_ID="100000";
menu.Menu_Name="第一级";
menu.Back_Menu_ID="0";
U5.OperationRule.Factory factory=new U5.OperationRule.Factory();
MessageBox.Show(factory.Add(menu));
}
这就是全部的代码,记事本的写的,如有运行不通过可以留言,这也是我对linq的基类的构成的理解,其实没有什么的,
当然我如果说的不对,大家指出