65.9K
CodeProject 正在变化。 阅读更多。
Home

用于在 LINQ to SQL 生成的类中执行插入/更新/获取/删除操作的泛型类

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (5投票s)

2011年8月12日

CPL

2分钟阅读

viewsIcon

24957

为了在 LINQ to SQL 生成的类上执行所有基本的 CRUD 操作,创建一个 BLL 或中间层的泛型类。

引言

本文创建了一个泛型类,只需一行代码即可执行基本的 CRUD 操作。本文的前提条件是我们需要拥有 LINQ to SQL 生成的类,因为该泛型类被设计成只能与 LINQ to SQL 生成的类一起工作。

Using the Code

关于如何使用文章或代码的简要说明。类名、方法和属性,任何技巧或窍门。

此泛型类的先决条件是我们需要拥有可用的 LINQ to SQL 生成的类。可以在此找到生成 LINQ to SQL 类的过程。

我们将假设 LINQ to SQL 类中的所有类都是实体,并且创建的 DataContext 类的名称是 TestDBContext。因此,我们需要创建一个名为 IEntity 的接口,其中包含泛型方法签名。接口的代码如下:

    // C# Code
    public interface IEntity<T> where T : class
    {
        IList<T> List();

        IList<T> List(int? page, int? pageSize, Expression<Func<T, bool>> predicate, Expression<Func<T, object>> sort);

        void Add(T item);

        T Get(Int64 Id);

        void Update(T item);

        bool Delete(T Item);

    }

要创建一个泛型类,我们需要实现此接口并将其命名为 Entity。在创建此类之前,我们需要在类中包含一些命名空间,即:

    // Namespaces included
    using System.Data.Linq;
    using System.Reflection;
    using System.Linq.Expressions;

在创建此泛型类时出现的主要问题是,数据库中的不同表可以将主键列定义为不同类型的数据类型。例如,一个表可能将其主键定义为“BIGINT”,而另一个表可能将其主键数据类型定义为“VARCHAR”。因此,为了使用此泛型类从这些表中获取数据,我们需要连同列的数据类型一起发送列名。我的泛型类将根据定义的参数确定类的属性并返回结果。表的其他操作比较简单,只需要 2-3 行代码即可。

Entity 类的代码

    public class Entity<T> : IEntity<T> where T : class
    {
    
        // Inserts the data values in the LINQ to SQL generated class.
        public virtual void Add(T item)
        {
            using (TestDBContext db = new TestDBContext())
            {
                db.GetTable<T>().InsertOnSubmit(item);
                db.SubmitChanges();
            }
        }

        // Returns the list of the object of LINQ to SQL Class
        public virtual IList<T> List()
        {
            using (TestDBContext db = new TestDBContext())
            {
                return db.GetTable<T>().ToList();
            }
        }

        // Returns the list of the object of LINQ to SQL Class on the basis of parameters
        public virtual IList<T> List(int? page, int? pageSize, System.Linq.Expressions.Expression<Func<T, bool>> predicate, System.Linq.Expressions.Expression<Func<T, object>> sort)
        {
            var result = this.List().AsQueryable();

            if (predicate != null)
                result = result.Where(predicate);

            if (sort != null)
                result = result.OrderBy(sort);

            if (page.HasValue && pageSize.HasValue)
                result = result.Skip((page.Value - 1) * pageSize.Value).Take(pageSize.Value);

            return result.ToList();
        }

        // Returns the object on the basis of the objects ID, if ID datatype is Int64.
        public virtual T Get(Int64 value)
        {
            return Get(typeof(System.Int64), "ID", value);
        }

        // Returns the object on the basis of the objects ID, if ID datatype is String.
        public virtual T Get(string value)
        {
            return Get(typeof(System.String), "ID", value);
        }

        // Returns the object on the basis of the objects property column.
        public virtual T Get(Type propertyType, string propertyName, object propertyValue)
        {
            T result = null;
            using (TestDBContext db = new TestDBContext())
            {
                IQueryable<T> queryableData = db.GetTable<T>().AsQueryable<T>();
                if (queryableData != null)
                {
                    ParameterExpression pe = Expression.Parameter(typeof(T), "entity");

                    Expression left = Expression.Property(pe, GetPropertyInfo(propertyName));
                    Expression right = Expression.Constant(propertyValue, propertyType);

                    Expression predicateBody = Expression.Equal(left, right);

                    MethodCallExpression whereCallExpression = Expression.Call(
                        typeof(Queryable),
                        "Where",
                        new Type[] { queryableData.ElementType },
                        queryableData.Expression,
                        Expression.Lambda<Func<T, bool>>(predicateBody, new ParameterExpression[] { pe }));

                    IQueryable<T> results = queryableData.Provider.CreateQuery<T>(whereCallExpression);
                    foreach (T item in results)
                    {
                        result = item;
                        break;
                    }
                }
                return result;
            }
        }

        // Updates the data values in the LINQ to SQL generated class.
        public virtual void Update(T item)
        {
            using (TestDBContext db = new TestDBContext())
            {
                db.GetTable<T>().Attach(item, true);
                db.SubmitChanges();
            }
        }

        // Deletes the data values in the LINQ to SQL generated class.
        public virtual bool Delete(T Item)
        {
            using (TestDBContext db = new TestDBContext())
            {
                db.GetTable<T>().DeleteOnSubmit(Item);
                db.SubmitChanges();
                return true;
            }
        }

        private PropertyInfo GetPropertyInfo(string propertyName)
        {
            PropertyInfo[] properties = typeof(T).GetProperties();
            PropertyInfo result = null;
            foreach (PropertyInfo pi in properties)
            {
                if (pi.Name.Equals(propertyName))
                {
                    result = pi;
                    break;
                }
            }
            return result;
        }

    }

调用 Entity 类进行 CRUD 操作的示例

    //Suppose we have a class named 'NOTEs' generated by the LINQ to SQL.

    // Code to add the object values
    NOTES obj = new NOTES();
    obj.CATEGORY = 'First Category';
    obj.SUBJECT = 'Subject of the Category';
    obj.NODETEXT = 'Sample text of the Node';

    Entity<NOTES> entity = new Entity</NOTES>();
    entity.Add(obj);

    // Code to get the object values
    Entity<NOTES> entity = new Entity<NOTES>();
    NOTES note = entity.Get(typeof(System.Int64), "ID", 1);

    ....

关注点

如何:创建 LINQ to SQL 类
如何:使用表达式树

© . All rights reserved.