c# - 在没有 Entity Framework 的情况下使用 C# 进行数据库交互

标签 c# .net sql-server ado.net

我接到了一项任务,我需要显示一个表单,该表单的数据驻留在 Sql server 的各种表中。要求严格不要使用 Entity Framework 或存储过程。在这种情况下,我有什么选择?

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

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

最佳答案

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

  • Person_Id INT PRIMARY KEY NOT NULL
  • 名称 NVARCHAR(100) NULL

电子邮件

  • Person_Id INT PRIMARY KEY NOT NULL
  • Email_Id INT PRIMARY KEY NOT NULL
  • 电子邮件 NVARCHAR(100) NOT NULL

    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;
        }
    }
    

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

关于c# - 在没有 Entity Framework 的情况下使用 C# 进行数据库交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34958249/

相关文章:

c# - 追加两个多维数组对象 [,]

c# - 使用类型名称将 JSON 文本反序列化为特定对象类型

c# - 正则表达式以字符集开始和结束,但中间有不同的字符集

php mssql mysql集成错误

c# - 厘米到像素

c# - 使用 AngleSharp 获取和下载图片

c# - 何时使用 this 关键字作为函数参数

c# - 什么更喜欢与 asp.net 网站集成的 Windows 服务或进程来编码文件?

sql - T-SQL 字符串连接多行

sql - 如何在 SQL Server Management Studio 中关闭与本地数据库的所有连接?