使用不带实体框架的 C# 进行数据库交互

本文关键字:数据库 交互 框架 实体 | 更新日期: 2023-09-27 18:31:35

我被分配了一个任务,我需要显示一个表单,其数据驻留在 Sql 服务器的各个表中。要求是严格不使用实体框架或存储过程。在这种情况下,我有什么选择?

目前,我正在使用SqlCommand对象运行一些sql查询,但是在获取关系数据然后允许用户从表单中更新它时,事情变得非常复杂。

Winforms中允许查看和编辑关系数据的最佳方法/方法是什么?

使用不带实体框架的 C# 进行数据库交互

您可以为需要访问/更新的对象编写自己的简单类。出于以下示例的目的,假设您有 2 个表:

  • Person_Id int 主键不为空
  • 名称 NVARCHAR(100) 空

电子邮件

  • Person_Id int 主键不为空
  • Email_Id int 主键不为空
  • 电子邮件 NVARCHAR(100) 不空

    public class MyProgram
    {
        public List<Person> ReadRecords()
        {
            // Set up your connection
            SqlConnection conn = new SqlConnection();
            conn.Open();
            SqlCommand cmd = new SqlCommand("SELECT * FROM Person", conn);
            SqlDataReader reader = cmd.ExecuteReader();
            List<Person> personRecords = new List<Person>();
            while (reader.Read())
            {
                Person p = new Person(reader, conn);
                personRecords.Add(p);
            }
            return personRecords;
        }
        public int UpdateRecords(IEnumerable<Person> records, SqlConnection conn)
        {
            int personsUpdated = 0;
            int recordsUpdated = 0;
            foreach (Person p in records)
            {
                if (p.Changed)
                {
                    recordsUpdated += p.Update(conn);
                    personsUpdated++;
                }
            }
            return recordsUpdated;
        }
    }
    public class Person
    {
        public const string SqlGetPersonEmailsCommand = "SELECT Email_Id, Email FROM Emails WHERE Person_Id = @Person_Id";
        public const string SqlUpdatePersonCommand = "UPDATE Person SET Name = @Name WHERE Id = @OriginalId";
        public const string SqlUpdatePersonEmailCommand = "UPDATE Emails SET Email = @Email WHERE Email_Id = @Email_Id";
        public int OriginalId { get; private set; }
        private bool personChanged;
        private bool emailsChanged { get { return changedEmails.Count > 0; } }
        public bool Changed { get { return personChanged || emailsChanged; } }
        private int _id;
        public int Id
        {
            get { return _id; }
            set
            {
                throw new Exception("Changing Id is not allowed.");
            }
        }
        private string _name;
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                personChanged = true;
            }
        }
        private List<int> changedEmails;
        private Dictionary<int, string> _emailAddresses;
        public string[] EmailAddresses
        {
            get
            {
                string[] values = new string[_emailAddresses.Count];
                _emailAddresses.Values.CopyTo(values, 0);
                return values;
            }
        }
        public void UpdateEmail(int emailId, string newEmail)
        {
            _emailAddresses[emailId] = newEmail;
            changedEmails.Add(emailId);
        }
        public Person(IDataReader reader, SqlConnection conn)
        {
            // Read ID (primary key from column 0)
            OriginalId = _id = reader.GetInt32(0);
            // Check if value in column 1 is Null; if so, set _name to Null, otherwise read the value
            _name = reader.IsDBNull(1) ? null : reader.GetString(1);
            // Now get all emails for this Person record
            SqlCommand readEmailsCmd = new SqlCommand(SqlGetPersonEmailsCommand, conn);
            readEmailsCmd.Parameters.Add("@Person_Id", SqlDbType.Int);
            readEmailsCmd.Parameters["@Person_Id"].Value = OriginalId;
            SqlDataReader emailReader = readEmailsCmd.ExecuteReader();
            changedEmails = new List<int>();
            _emailAddresses = new Dictionary<int, string>();
            if (emailReader.HasRows)
            {
                while (emailReader.Read())
                {
                    int emailId = emailReader.GetInt32(0);
                    string email = emailReader.GetString(1);
                    _emailAddresses.Add(emailId, email);
                }
            }
        }
    
        public int Update(SqlConnection conn)
        {
            int rowsUpdated = 0;
            SqlCommand command = null;
            // Update Person record
            if (personChanged)
            {
                command = new SqlCommand(SqlUpdatePersonCommand, conn);
                command.Parameters.Add("@OriginalId", SqlDbType.Int);
                command.Parameters["@OriginalId"].Value = OriginalId;
                command.Parameters.Add("@Name", SqlDbType.NVarChar);
                command.Parameters["@Name"].Value = _name;
                rowsUpdated = command.ExecuteNonQuery();
            }
            // Now update all related Email records
            foreach (int id in changedEmails)
            {
                command = new SqlCommand(SqlUpdatePersonEmailCommand, conn);
                command.Parameters.Add("@Email_Id", SqlDbType.Int);
                command.Parameters["@Email_Id"].Value = id;
                command.Parameters.Add("@Email", SqlDbType.NVarChar);
                command.Parameters["@Email"].Value = _emailAddresses[id];
                rowsUpdated = +command.ExecuteNonQuery();
            }
            return rowsUpdated;
        }
    }
    

上面的示例支持更改人员的姓名和关联的电子邮件地址。

在这种情况下,我认为最好的方法是使用Dapper。您将非常接近 ADO.NET 并控制所有SQL查询。同时,您不会花时间在映射功能上 - 因为这非常简单,但耗时的代码部分。

  • 问题#1以"[除了实体框架]我有什么选择?"结尾,你在评论中得到了答案(直截了当 ADO.NET 或NHibernate)。你也知道这一点,因为你说你正在使用 SqlCommand。

  • 问题 #2 是困难的问题,我认为这就是您的导师希望您了解的:"Winforms 中允许查看和编辑关系数据的最佳方法/方法是什么?

我使用 Microsoft 堆栈为关系数据做了大量的 UI。但无论技术如何,您都需要一个好的模式或方法。简短的回答(不是一本书)是从 UI 中抽象数据。这样他们就可以独立工作,也可以独立改变。

首先意识到编辑数据和显示数据应该是程序的两个不同部分。我喜欢的一种方法是从SQL SERVER中选择您的关系数据作为XML,然后使用XSLT显示它:

<Customer>
    <Name>...
    <Company>...
    <Phone>...
    <BillingAddresses>
         <Address>...
         <Address>...
    <PayementMethods>
         <CreditCard>...
         <CreditCard>...
    <RecentOrders>
         <Order>...
         <Order>...
         <Order>...

您可以使用 XSLT 轻松地将其转换为看起来像您想要的任何内容的 HTML。在此示例中,在显示每个<Address><CreditCard>的位置旁边,您可以在每个部分下放置"编辑/删除"链接以及"添加"链接。

单击"编辑/删除/添加"将转到一个屏幕,以修改该部分的关系数据。当您返回到将 XML 显示为 HTML 的屏幕时,您将看到更新的数据。

这很好,因为您可以轻松地修改 XML,而无需重新编译代码。还可以使用 XSLT 以所需的任何布局显示数据。然后,您的 XML 可以包含存储为代码的内容的文本(AMX=AMERICAN EXPRESS,等等)。

无论如何,这只是一个没有实际要求的解决方案(例如支持"撤消",一次应用多个更改等)。

ADO.NET 是

数据库访问的最佳选择。这是 EF 所基于的技术。若要显示数据,大多数时间都使用数据绑定。用于保存和检索您使用的数据 ADO.NET。您可能不希望将 ADO 对象直接装箱到 UI,而是使用视图模型。但传统上和在文档中 ASP.NET 数据集通常直接绑定到UI女巫从今天看来是一种糟糕的编程风格。

创建数据集将是最佳选择。使用数据集的步骤1.右键单击您的项目,去添加=>新项目 =>数据集。那是.xsd格式文件。2.在该文件中右键单击数据集内,Agaign Add => 表适配器。从那里,您需要完成数据连接,然后选择表,开始编写查询。3. 完成创建后,可以直接将查询连接到类文件。