关于linq基类,随便写一写

本文深入探讨了LINQ的工作原理及其实现方式,通过自定义类似LINQ的基类代码,详细介绍了如何通过反射和映射来构建SQL语句。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      在网上看到大家都在学习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的基类的构成的理解,其实没有什么的,
当然我如果说的不对,大家指出

转载于:https://www.cnblogs.com/jimmyko/archive/2008/06/28/1231614.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值