欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

让ADO.NET Entity Framework 支持ACCESS数据库

程序员文章站 2022-06-02 16:49:32
...

如写的不好请见谅,本人水平有限。 个人简历及水平:。 http://www.cnblogs.com/hackdragon/p/3662599.html 接到一个程序和网页交互的项目,用ADO.NET Entity Framework (以下简称EF)很快就搞完了,但是对方的空间提供的MSSQL数据库比较昂贵,所以就采用AC

如写的不好请见谅,本人水平有限。

个人简历及水平:。 http://www.cnblogs.com/hackdragon/p/3662599.html

接到一个程序和网页交互的项目,用ADO.NET Entity Framework (以下简称EF)很快就搞完了,但是对方的空间提供的MSSQL数据库比较昂贵,所以就采用ACCESS数据库,但是我查了资料发现 EF不支持Access数据库,(以前觉得LINQ TO SQL 不支持 这个应该支持),写完的代码不想用OLEDB在写了,于是网上一顿查,试验了ALINQ和其他很多的,总是不能符合项目的需要。不是更新不行就算插入失败,要不就是经常查询错误。最后没办法,我自己决定写一个实体支持ACCESS数据库,我觉得懒人应该有需要这个的,当然大侠们估计有更好的办法来更懒一些。

懒人第一步:

因为VS的实体生成器不支持ACCESS数据库,所以无法生成代码,但是想快速开发项目,那么你可以用SQL数据库先来设计,然后导出数据库到ACCESS数据库,这样做的目的是让生成器可以生成我们所需要的代码。注意设计数据库字段的时候要考虑他们的兼容性。

勤快第二步:

开始写代码了,原始的上下文代码如下:

#region 上下文
    
    /// 
    /// 没有元数据文档可用。
    /// 
    public partial class SqlDoorEntities1 : ObjectContext
    {
        #region 构造函数
    
        /// 
        /// 请使用应用程序配置文件的“SqlDoorEntities1”部分中的连接字符串初始化新 SqlDoorEntities1 对象。
        /// 
        public SqlDoorEntities1() : base("name=SqlDoorEntities1", "SqlDoorEntities1")
        {
            OnContextCreated();
        }
    
        /// 
        /// 初始化新的 SqlDoorEntities1 对象。
        /// 
        public SqlDoorEntities1(string connectionString) : base(connectionString, "SqlDoorEntities1")
        {
            OnContextCreated();
        }
    
        /// 
        /// 初始化新的 SqlDoorEntities1 对象。
        /// 
        public SqlDoorEntities1(EntityConnection connection) : base(connection, "SqlDoorEntities1")
        {
            OnContextCreated();
        }
    
        #endregion
    
        #region 分部方法
    
        partial void OnContextCreated();
    
        #endregion
    
        #region ObjectSet 属性
    
        /// 
        /// 没有元数据文档可用。
        /// 
        public ObjectSet CmdMsg
        {
            get
            {
                if ((_CmdMsg == null))
                {
                    _CmdMsg = base.CreateObjectSet("CmdMsg");
                }
                return _CmdMsg;
            }
        }
        private ObjectSet _CmdMsg;
    
        /// 
        /// 没有元数据文档可用。
        /// 
        public ObjectSet Door
        {
            get
            {
                if ((_Door == null))
                {
                    _Door = base.CreateObjectSet("Door");
                }
                return _Door;
            }
        }
        private ObjectSet _Door;
    
        /// 
        /// 没有元数据文档可用。
        /// 
        public ObjectSet Manager
        {
            get
            {
                if ((_Manager == null))
                {
                    _Manager = base.CreateObjectSet("Manager");
                }
                return _Manager;
            }
        }
        private ObjectSet _Manager;
    
        /// 
        /// 没有元数据文档可用。
        /// 
        public ObjectSet Users
        {
            get
            {
                if ((_Users == null))
                {
                    _Users = base.CreateObjectSet("Users");
                }
                return _Users;
            }
        }
        private ObjectSet _Users;

        #endregion

        #region AddTo 方法
    
        /// 
        /// 用于向 CmdMsg EntitySet 添加新对象的方法,已弃用。请考虑改用关联的 ObjectSet<T> 属性的 .Add 方法。
        /// 
        public void AddToCmdMsg(CmdMsg cmdMsg)
        {
            base.AddObject("CmdMsg", cmdMsg);
        }
    
        /// 
        /// 用于向 Door EntitySet 添加新对象的方法,已弃用。请考虑改用关联的 ObjectSet<T> 属性的 .Add 方法。
        /// 
        public void AddToDoor(Door door)
        {
            base.AddObject("Door", door);
        }
    
        /// 
        /// 用于向 Manager EntitySet 添加新对象的方法,已弃用。请考虑改用关联的 ObjectSet<T> 属性的 .Add 方法。
        /// 
        public void AddToManager(Manager manager)
        {
            base.AddObject("Manager", manager);
        }
    
        /// 
        /// 用于向 Users EntitySet 添加新对象的方法,已弃用。请考虑改用关联的 ObjectSet<T> 属性的 .Add 方法。
        /// 
        public void AddToUsers(Users users)
        {
            base.AddObject("Users", users);
        }

        #endregion

    }

    #endregion

ObjectContext 继承于IDisposable 那么我写一个自己的 ObjectContext 这样的类 我给他起个名字叫EFToAccess 那么多 构造方法 我们就需要2个一个 是 给定的连接字符串 一个是默认从webconfig中读取的链接字符串就可以了。本人偷懒,直接读取指定的路径了。数据库的简单读写可能都依赖一个where查询,那么怎么实现自己的where查询就很关键,于是我看资料研究了2天Lambda Expression 表达式。最后还是看了 博客园的一篇 扩展LINQ to SQL:使用Lambda Expression批量删除数据才会用,现在也不是很明白,懒人就是拿来主义,不怎么消化,我现在也没多少时间消化知识,估计这样的人也不少吧。下面是我自己用的的方法,利用VS生成的代码 2个替换1个删除搞定 (ObjectContext替换“你自己的类名我的是SqlDoorEntities”,ObjectSet替换成IEnumerable,删除无用的构造函数)

public class SqlDoorEntities : EFToAccess
    {
        public SqlDoorEntities():base("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" 
+AppDomain.CurrentDomain.BaseDirectory + "bin\\DataDoor.mdb")

        {
        }
        #region IEnumerable 属性
        /// 
        /// 没有元数据文档可用。
        /// 

        public IEnumerable CmdMsg
        {
            get
            {
                if ((_CmdMsg == null))
                {
                    _CmdMsg = base.CreateObjectSet("CmdMsg");
                }
                return _CmdMsg;
            }
        }
        private IEnumerable _CmdMsg;

        /// 
        /// 没有元数据文档可用。
        /// 
        public IEnumerable Door
        {
            get
            {
                if ((_Door == null))
                {
                    _Door = base.CreateObjectSet("Door");
                }
                return _Door;
            }
        }
        private IEnumerable _Door;

        /// 
        /// 没有元数据文档可用。
        /// 
        public IEnumerable Manager
        {
            get
            {
                if ((_Manager == null))
                {
                    _Manager = base.CreateObjectSet("Manager");
                }
                return _Manager;
            }
        }
        private IEnumerable _Manager;

        /// 
        /// 没有元数据文档可用。
        /// 
        public IEnumerable Users
        {
            get
            {
                if ((_Users == null))
                {
                    _Users = base.CreateObjectSet("Users");
                }
                return _Users;
            }
        }
        private IEnumerable _Users;

        #endregion
        #region AddTo 方法

        /// 
        /// 用于向 CmdMsg EntitySet 添加新对象的方法,已弃用。请考虑改用关联的 IEnumerable<T> 属性的 .Add 方法。
        /// 
        public void AddToCmdMsg(CmdMsg cmdMsg)
        {
            base.AddObject("CmdMsg", cmdMsg);
        }

        /// 
        /// 用于向 Door EntitySet 添加新对象的方法,已弃用。请考虑改用关联的 IEnumerable<T> 属性的 .Add 方法。
        /// 
        public void AddToDoor(Door door)
        {
            base.AddObject("Door", door);
        }

        /// 
        /// 用于向 Manager EntitySet 添加新对象的方法,已弃用。请考虑改用关联的 IEnumerable<T> 属性的 .Add 方法。
        /// 
        public void AddToManager(Manager manager)
        {
            base.AddObject("Manager", manager);
        }

        /// 
        /// 用于向 Users EntitySet 添加新对象的方法,已弃用。请考虑改用关联的 IEnumerable<T> 属性的 .Add 方法。
        /// 
        public void AddToUsers(Users users)
        {
            base.AddObject("Users", users);
        }

        #endregion
    }

懒人第三步:

为了让代码和EF使用方法基本一致,所以不得不做一些工作让我写的类基本满足项目需要。首先实现一个让Lambda Expression 表达式变成字符串的函数

string GetWhereString(Expression Func)
        {
            ConditionBuilder conditionBuilder = new ConditionBuilder();
            conditionBuilder.Build(Func);
            for (int i = 0; i )
            {