问题 将datagridview单元格值更改更新到3层体系结构中的数据库

安德鲁·马努亚

知名会员
已加入
五月30,2019
留言内容
75
编程经验
Beginner
大家好,
我目前正在努力

请在下面找到相应的数据访问层代码;

C#:
 public void UpdateUser(PersonDTO bPerson)
        {
            using (SqlConnection conn = new SqlConnection(_connStr))

            using (var dCmd = new SqlCommand(@"UPDATE Person SET FirstName = @FirstName, LastName = @LastName, Age = @Age WHERE PersonID = @PersonID", conn))

            using (var adapter = new SqlDataAdapter { UpdateCommand = dCmd })
            {
                conn.Open();
                dCmd.Parameters.AddWithValue("personID", bPerson.PersonID);
                dCmd.Parameters.AddWithValue("firstName", bPerson.FirstName);
                dCmd.Parameters.AddWithValue("lastName", bPerson.LastName);
                dCmd.Parameters.AddWithValue("age", bPerson.Age);

                try
                {
                    adapter.Update(table);
                    dCmd.Dispose();
                }

                catch (Exception ex)
                {
                    throw ex;
                }
            }

            foreach (DataRow row in table.Rows)
            {
                if (row["Select Item"] as bool? == true)
                {
                    table.AcceptChanges();
                    row.SetAdded();                  
                }
            }
        }

我的业务逻辑层代码如下所示;
C#:
 public void UpdateUser(PersonDTO bPerson)
        {        

            try
            {
                personDAL.UpdateUser(bPerson);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

我有点困惑如何编写btnUpdate(更新按钮)的代码以将datagridview数据更新到数据库表。只是叫业务访问层"UpdateUser" method?

请稍作澄清,由于我绑定了数据表,"table"作为dataGridView的数据源,我假设对datagridview单元格数据进行的任何更改都会自动更新数据表,"table'.

感谢您的反馈。

亲切的问候,

安德鲁
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,524
地点
悉尼,澳大利亚
编程经验
10+
您使用n层的事实并没有真正改变您需要做的事情。这 数据表 是模型。你的 点击按钮 事件处理程序将调用业务逻辑层中的方法并将其传递给 数据表。该方法将调用数据访问层中的方法以将更改保存到数据库。完毕。与以往一样,更改将使用数据适配器保存。您可能要创建一个 复制数据表 首先,确保任何问题都不会影响绑定数据。然后,您可以通过适当的方式返回布尔值以指示成功或失败,并在成功时调用 接受变更 明确地在原件上 数据表。
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,524
地点
悉尼,澳大利亚
编程经验
10+
数据是模型,它在各层之间上下传递。您可能会或可能不会在图层边界进行转换。例如,在我们构建的某些Web应用程序中,我们在Web服务中使用Entity Framework,然后映射到DTO。该网站调用该服务并接收那些DTO,然后映射到视图模型并传递给适当的视图。然后,将过程反向进行保存。如果没有这些转换,则可以通过相同的转换 数据表 一路向上,然后一路向下。
 

安德鲁·马努亚

知名会员
已加入
五月30,2019
留言内容
75
编程经验
Beginner
嗨,jmcilhinney,
感谢您的宝贵意见。
是的,我在应用程序中使用数据传输对象。

根据我的理解,我在数据访问层下编写了以下代码,看起来像;

C#:
using (SqlConnection conn = new SqlConnection(_connStr))

            using (var dCmd = new SqlCommand(@"UPDATE Person SET FirstName = @FirstName, LastName = @LastName, Age = @Age WHERE PersonID = @PersonID", conn))

            using (var adapter = new SqlDataAdapter { UpdateCommand = dCmd })
            {
                conn.Open();
                dCmd.Parameters.AddWithValue("personID", bPerson.PersonID);
                dCmd.Parameters.AddWithValue("firstName", bPerson.FirstName);
                dCmd.Parameters.AddWithValue("lastName", bPerson.LastName);
                dCmd.Parameters.AddWithValue("age", bPerson.Age);

                try
                {
                    foreach (DataRow dr in table.Rows)
                    {                       
                      tablecopy.Rows.Add(dr.ItemArray);
                    }
                    adapter.Update(table);
                    dCmd.Dispose();                                     
                }

                catch (Exception ex)
                {
                    throw ex;
                }
            }

            foreach (DataRow row in table.Rows)
            {
                if (row["Select Item"] as bool? == true)
                {
                    table.AcceptChanges();
                    row.SetAdded();                   
                }
            }
            return true;

我更新后的业务逻辑层看起来像;

C#:
 public bool UpdateUser(PersonDTO bPerson)
        {

            try
            {
                return personDAL.UpdateUser(bPerson);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

最后,btnUpdate事件下的代码如下所示;

C#:
  foreach (DataRow row in table.Rows)
            {
                int dpersonID = Convert.ToInt32(row.Table.Columns["textPersonID"].ToString());
                string dfirstname = Convert.ToString(row.Table.Columns["textFirstName"].ToString());
                string dlastname = Convert.ToString(row.Table.Columns["textLastName"].ToString());
                int dage = Convert.ToInt32(row.Table.Columns["textAge"].ToString());

                PersonDTO newPerson = new PersonDTO();

                newPerson.PersonID = dpersonID;
                newPerson.FirstName = dfirstname;
                newPerson.LastName = dlastname;
                newPerson.Age = dage;

                try
                {

                    bool personUpdate = personBal.UpdateUser(newPerson);
                    if (personUpdate != true)
                    {
                        MessageBox.Show("No data found to update");
                    }
                    else
                    {
                        //personBal.UpdateUser(newPerson);                       
                        MessageBox.Show("Data updated successfully");
                        return;
                    }
                }
                catch (Exception ee)
                {
                    MessageBox.Show(ee.Message);
                }
            }

但是,更新方法不会触发。

请感谢您的反馈。

谢谢你。

亲切的问候,

安德鲁
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,536
地点
弗吉尼亚州切萨皮克
编程经验
10+
但是,更新方法不会触发。
Well as you surmised to get entire train moving, you need that update method to work. The question is: Did you remember to hook up the event receiver to your btnUpdate click handler? Remember that VB.NET WinForm, and ASP.NET WebForms have "auto-wiring",但C#WinForms不会。
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,524
地点
悉尼,澳大利亚
编程经验
10+
你说:
最后,btnUpdate事件下的代码如下所示
但是没有代码"under a Button"。该代码位于方法中,该方法是表单的一部分,并且假定该方法可以处理 点击 你的事件 按钮。那不会完全发生。您必须通过将方法注册为该事件的处理程序来实现它。你做完了吗?如果没有,这就是为什么当您单击 按钮。当您在窗体设计器中双击一个控件时,将生成一个方法并将其注册为该控件的默认事件的处理程序。如果您自己添加方法,则也需要添加注册。您可以在代码中做到这一点,它看起来像这样:
C#:
myObject.SomeEvent += SomeMethod;
但是,如果要谈论在设计器中添加的控件,则可以使用“属性”窗口来完成。单击该窗口中的“事件”按钮,您可以双击事件以生成事件处理程序,或从下拉列表中选择现有方法。如果打开设计器代码文件,则可以看到通过设计器添加的所有事件处理程序注册。
 

安德鲁·马努亚

知名会员
已加入
五月30,2019
留言内容
75
编程经验
Beginner
嗨,jmcilhinney,

感谢您的反馈意见。

我已使用设计器窗口并通过双击创建事件"btnUpdate" controller.
请参考下面的代码块
C#:
private void btnUpdate_Click(object sender, EventArgs e)
        {   
            foreach (DataRow row in personBal.LoadAll().Rows)             
             {
                
            }

实际上,我正在向数据访问层中的数据表添加一个布尔数据列,并从数据库表中加载数据。

触发更新事件时,我将数据表中的值转换为参数,并传递给它们以执行btnUpdate事件。

因此,我的数据表"table"看起来像下面的东西;

数据表(表)窗口Image.png


我有几个问题,
1.在将数据传递到数据访问层时,我应该声明一个DTO"Select Item"柱子?这是因为sql数据库表没有用于"Select Item"。但是,如果需要,我可以使用以下内容吗?
C#:
bool selectItem = Convert.ToBoolean(row.Table.Columns ["Select Item"].ToString());
2.将数据表数据转换为参数时出现错误,
C#:
 int personID = Convert.ToInt32(row.Table.Columns["PersonID"].ToString());

请感谢您的宝贵反馈。

先感谢您。

亲切的问候,

安德鲁
 

安德鲁·马努亚

知名会员
已加入
五月30,2019
留言内容
75
编程经验
Beginner
嗨,jmcilhinney,

1.在将数据传递到数据访问层时,我应该声明一个DTO"Select Item"柱子?这是因为sql数据库表没有用于"Select Item"。但是,如果需要,我可以使用以下内容吗?
C#:

bool selectItem = Convert.ToBoolean(row.Table.Columns ["Select Item"].ToString());

抱歉,是的,我认为需要发送"Select Item"另外,由于我正在数据访问层中执行验证,因此将更新保存到数据库表中。

谢谢你。

亲切的问候,
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,524
地点
悉尼,澳大利亚
编程经验
10+
这有什么意义 选择物品 柱子?是否专门用于选择要保存的项目?如果是这样,那仅是表示问题,因此信息应仅存在于表示层中。数据访问层应该关心这一点,因为它只应接收要保存的记录的数据。这是一个示例,说明我可能如何做我认为您要尝试做的事情:
C#:
public class DataAccess
{
    public DataTable GetPeopleSchema()
    {
        var table = new DataTable();

        using (var adapter = new SqlDataAdapter("SELECT * FROM Person", "connection string here"))
        {
            adapter.FillSchema(table, SchemaType.Source);
        }

        return table;
    }

    public DataTable GetPeople()
    {
        var table = new DataTable();

        using (var adapter = new SqlDataAdapter("SELECT * FROM Person", "connection string here"))
        {
            adapter.Fill(table);
        }

        return table;
    }

    public void SavePeople(DataTable table)
    {
        using (var connection = new SqlConnection("connection string here"))
        using (var command = new SqlCommand("UPDATE Person SET GivenName = @GivenName, FamilyName = @FamilyName, DateOfBirth = @DateOfBirth WHERE PersonId = @PersonId", connection))
        using (var adapter = new SqlDataAdapter {UpdateCommand = command})
        {
            command.Parameters.Add("@GivenName", SqlDbType.VarChar, 50, "GivenName");
            command.Parameters.Add("@FamilyName", SqlDbType.VarChar, 50, "FamilyName");
            command.Parameters.Add("@DateOfBirth", SqlDbType.DateTime2, 0, "DateOfBirth");
            command.Parameters.Add("@ParentId", SqlDbType.Int, 0, "ParentId");

            adapter.Update(table);
        }
    }
}


public class BusinessLogic
{
    private readonly DataAccess dataAccess = new DataAccess();

    public List<PersonDto> GetPeople()
    {
        var table = dataAccess.GetPeople();
        var people = table.AsEnumerable()
                                      .Select(row => new PersonDto
                                                     {
                                                         PersonId = row.Field<int>(nameof(PersonDto.PersonId)),
                                                         GivenName = row.Field<string>(nameof(PersonDto.GivenName)),
                                                         FamilyName = row.Field<string>(nameof(PersonDto.FamilyName)),
                                                         DateOfBirth = row.Field<DateTime>(nameof(PersonDto.DateOfBirth))
                                                     })
                                      .ToList();

        return people;
    }

    public void SavePeople(List<PersonDto> people)
    {
        var table = dataAccess.GetPeopleSchema();

        foreach (var person in people)
        {
            var row = table.NewRow();

            row.ItemArray = new object[]
                            {
                                person.PersonId,
                                person.GivenName,
                                person.FamilyName,
                                person.DateOfBirth
                            };
            table.Rows.Add(row);
            row.SetModified();
        }

        dataAccess.SavePeople(table);
    }
}

public class PersonDto
{
    public int PersonId { get; set; }
    public string GivenName { get; set; }
    public string FamilyName { get; set; }
    public DateTime DateOfBirth { get; set; }
}


public class Presentation
{
    private readonly BusinessLogic businessLogic = new BusinessLogic();

    public void DisplayPeople()
    {
        var personDtos = businessLogic.GetPeople();
        var people = personDtos.Select(dto => new PersonModel(dto)).ToList();
        var peopleForm = new PeopleForm(people);

        peopleForm.Show();
    }

    public void SavePeople(List<PersonModel> people)
    {
        var personDtos = people.Where(p => p.IsSelected)
                                           .Select(p => new PersonDto
                                                                 {
                                                                     PersonId = p.PersonId,
                                                                     GivenName = p.GivenName,
                                                                     FamilyName = p.FamilyName,
                                                                     DateOfBirth = p.DateOfBirth
                                                                 })
                                           .ToList();

        businessLogic.SavePeople(personDtos);
    }
}

public class PersonModel : PersonDto
{
    public bool IsSelected { get; set; }

    public PersonModel(PersonDto person)
    {
        PersonId = person.PersonId;
        GivenName = person.GivenName;
        FamilyName = person.FamilyName;
        DateOfBirth = person.DateOfBirth;
        IsSelected = false;
    }
}
这显然得到了简化,我可能会使用AutoMapper之类的方法在每个点上映射数据,但希望您能理解。
 

安德鲁·马努亚

知名会员
已加入
五月30,2019
留言内容
75
编程经验
Beginner
嗨,jmcilhinney,

非常感谢您的宝贵意见。

我目前正在研究您的解决方案,并致力于在Windows Form环境中实施。

不过,再次非常感谢您,如果需要任何澄清,我们会尽快与您联系。

亲切的问候,

安德鲁
 
最佳 底部