c#winform,不能从dbnull到其他类型的对象

发布于 2025-02-02 18:58:55 字数 2675 浏览 1 评论 0原文

我的数据杂志中有复选框,可以从已经从数据库中加载的数据中删除一个或多个行。 DataSource是DataBindingSource。 我想首先检查用户是否检查了一个或多个复选框,这是我要检查的代码。

int total = dgvRegister.Rows.Cast<DataGridViewRow>().Where(x => Convert.ToBoolean(x.Cells["Delete"].Value) == true).Count();
if (total > 0)
{
// Do something

}

但是我遇到了这个错误“对象不能从dbnull施放到其他类型”。我很高兴,但没有帮助。 请帮助我解决这个问题,并提前非常感谢。

这是孔代码

private void btnDeActivateComputers_Click(object sender, EventArgs e)
    {
        try
        {
            using (CompEntities db = new CompEntities())
            {
                if (dgvRegister.Rows.Count > 0)
                {
                    int total = dgvRegister.Rows.Cast<DataGridViewRow>().Where(x => Convert.ToBoolean(x.Cells["Delete"].Value) == true).Count();
                    if (total > 0)
                    {
                         
                        if (MessageBox.Show("Do you want to delete?", "Deleting", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                        {
                            for (int i = dgvRegister.RowCount - 1; i >= 0; i--)
                            {
                                DataGridViewRow row = dgvRegister.Rows[i];
                                if (Convert.ToBoolean(row.Cells["Delete"].Value) == true)
                                {
                                    int ComId = Convert.ToInt32(dgvRegister.Rows[row.Index].Cells[0].Value.ToString());
                                    var deletecomp = db.Comp.Where(x => x.ComId == cId).FirstOrDefault();
                                    if (deletecomp != null)
                                    {
                                        db.Comp.Remove(deletecomp);


                                    }


                                    db.SaveChanges();

                                }
                            }
                        }


                        

                    }
                    else
                    {
                        MessageBox.Show("Please Check at least one checkbox !", "Information", MessageBoxButtons.OK,
                        MessageBoxIcon.Error,
                        MessageBoxDefaultButton.Button1);
                    }
                }
                 
            }

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            Exception inner = ex.InnerException;
            while (inner != null)
            {
                MessageBox.Show(inner.Message);
                inner = inner.InnerException;
            }
        }
        
    }

I have checkbox in my DataGridView to delete one or multiple rows from my DataGridView already loaded data from database. DataSource is dataBindingSource.
I want to check first if the user checked one or multiple checkboxes and here is my code to check.

int total = dgvRegister.Rows.Cast<DataGridViewRow>().Where(x => Convert.ToBoolean(x.Cells["Delete"].Value) == true).Count();
if (total > 0)
{
// Do something

}

But I'am geting this error "object cannot be cast from dbnull to other types". I have gogled but not s omuch to help.
Please help me to solv this problem and thanks a lot in advance.

Here is the hole code

private void btnDeActivateComputers_Click(object sender, EventArgs e)
    {
        try
        {
            using (CompEntities db = new CompEntities())
            {
                if (dgvRegister.Rows.Count > 0)
                {
                    int total = dgvRegister.Rows.Cast<DataGridViewRow>().Where(x => Convert.ToBoolean(x.Cells["Delete"].Value) == true).Count();
                    if (total > 0)
                    {
                         
                        if (MessageBox.Show("Do you want to delete?", "Deleting", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                        {
                            for (int i = dgvRegister.RowCount - 1; i >= 0; i--)
                            {
                                DataGridViewRow row = dgvRegister.Rows[i];
                                if (Convert.ToBoolean(row.Cells["Delete"].Value) == true)
                                {
                                    int ComId = Convert.ToInt32(dgvRegister.Rows[row.Index].Cells[0].Value.ToString());
                                    var deletecomp = db.Comp.Where(x => x.ComId == cId).FirstOrDefault();
                                    if (deletecomp != null)
                                    {
                                        db.Comp.Remove(deletecomp);


                                    }


                                    db.SaveChanges();

                                }
                            }
                        }


                        

                    }
                    else
                    {
                        MessageBox.Show("Please Check at least one checkbox !", "Information", MessageBoxButtons.OK,
                        MessageBoxIcon.Error,
                        MessageBoxDefaultButton.Button1);
                    }
                }
                 
            }

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            Exception inner = ex.InnerException;
            while (inner != null)
            {
                MessageBox.Show(inner.Message);
                inner = inner.InnerException;
            }
        }
        
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

忘东忘西忘不掉你 2025-02-09 18:58:55

这是一个使用实体框架核心和C#9的模式,如果使用.NET Framework 4.8,则需要进行一些调整,但是原理与下面指出的相同。

模型类别其中检查属性不是基础表的一部分。[notmapped]告诉Entity框架在[DefaultValue时都排除此属性(false)]提供false作为默认值。

public class Categories
{
    [NotMapped]
    [DefaultValue(false)]
    public bool Checked { get; set; }
    public int CategoryId { get; set; }
    public string CategoryName { get; set; }
}

在表单中,创建一个bindingsource,用于所有操作,曾经分配为DataGridView的数据源。如各种注释中所述,需要通过DataGridView引用数据。

注释

  • 代码为C#9,如果不使用.NET Core,则需要进行较小的调整。
  • 在删除记录的按钮中,使用lambda语句来获取
  • 项目
  • 检查 该代码。
  • DataGridView列是在DataGridView Designer中创建的,每个列datapropertyname设置为模型

表单代码的属性,其中有两个属于自己的文件中的类。

namespace StackoverflowCodeSample
{
    public partial class Form1 : Form
    {
        private readonly BindingSource _bindingSource = new();

        public Form1()
        {
            InitializeComponent();

            dataGridView1.AutoGenerateColumns = false;
            Shown += OnShown;

        }

        private void OnShown(object sender, EventArgs e)
        {
            using var context = new NorthwindContext();

            _bindingSource.DataSource = context.Categories.ToList();
            dataGridView1.DataSource = _bindingSource;

        }

        private void GetCheckedButton_Click(object sender, EventArgs e)
        {

            var checkedCategories =
                ((List<Categories>)_bindingSource.DataSource)
                .Where(category => category.Checked)
                .ToList();


            if (checkedCategories.Count > 0)
            {
                /*
                 * Prompt to remove selected entities
                 * Remove from database table, save
                 * if save changes is successful
                 *    Remove from BindingSource
                 * else
                 *    inform user of issues
                 */

                if (Dialogs.Question($"Remove {checkedCategories.Count} items?"))
                {
                    var (success, exception) = DataOperations
                        .RemoveRange(checkedCategories);

                    if (success)
                    {
                        for (int index = 0; index < checkedCategories.Count; index++)
                        {
                            _bindingSource.Remove(checkedCategories[index]);
                        }
                    }
                    else
                    {
                        MessageBox.Show($"Removal failed with\n{exception.Message}");
                    }
                }
            }
        }
    }

    public class DataOperations
    {
        public static (bool success, Exception exception) RemoveRange(List<Categories> list)
        {
            try
            {
                // remove items here
                // Set each entity state
                // perform SaveChanges
                return (true, null);
            }
            catch (Exception e)
            {
                return (false, e);
            }
        }
    }
    public static class Dialogs
    {
        public static bool Question(string text)
        {
            return (MessageBox.Show(
                text,
                "Question",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Question,
                MessageBoxDefaultButton.Button2) == DialogResult.Yes);
        }
    }
}

Here is a pattern to following using Entity Framework Core and C#9, some adjustments are needed if using say .NET Framework 4.8 but the principles are the same as noted below.

Model Categories where Checked property is not part of the underlying table.[NotMapped] tells Entity Framework to exclude this property while [DefaultValue(false)] provides false as the default value.

public class Categories
{
    [NotMapped]
    [DefaultValue(false)]
    public bool Checked { get; set; }
    public int CategoryId { get; set; }
    public string CategoryName { get; set; }
}

In the form, create a BindingSource which is used for all operations once assigned as the DataSource to the DataGridView. As mentioned in various comments, there is zero need to reference data via the DataGridView.

Notes

  • Code is C#9, minor adjustments will be needed if not using .NET Core.
  • In the button to remove records a lambda statement is used to get checked items
  • A wrapper for MessageDialog is used to ask permission to remove data
  • A class is provided to where you would remove the records but doesn't actually remove records, you need to write that code.
  • DataGridView columns were created in the DataGridView designer and each column DataPropertyName set to properties from the model

Form code with two classes that belong in their own files.

namespace StackoverflowCodeSample
{
    public partial class Form1 : Form
    {
        private readonly BindingSource _bindingSource = new();

        public Form1()
        {
            InitializeComponent();

            dataGridView1.AutoGenerateColumns = false;
            Shown += OnShown;

        }

        private void OnShown(object sender, EventArgs e)
        {
            using var context = new NorthwindContext();

            _bindingSource.DataSource = context.Categories.ToList();
            dataGridView1.DataSource = _bindingSource;

        }

        private void GetCheckedButton_Click(object sender, EventArgs e)
        {

            var checkedCategories =
                ((List<Categories>)_bindingSource.DataSource)
                .Where(category => category.Checked)
                .ToList();


            if (checkedCategories.Count > 0)
            {
                /*
                 * Prompt to remove selected entities
                 * Remove from database table, save
                 * if save changes is successful
                 *    Remove from BindingSource
                 * else
                 *    inform user of issues
                 */

                if (Dialogs.Question(
quot;Remove {checkedCategories.Count} items?"))
                {
                    var (success, exception) = DataOperations
                        .RemoveRange(checkedCategories);

                    if (success)
                    {
                        for (int index = 0; index < checkedCategories.Count; index++)
                        {
                            _bindingSource.Remove(checkedCategories[index]);
                        }
                    }
                    else
                    {
                        MessageBox.Show(
quot;Removal failed with\n{exception.Message}");
                    }
                }
            }
        }
    }

    public class DataOperations
    {
        public static (bool success, Exception exception) RemoveRange(List<Categories> list)
        {
            try
            {
                // remove items here
                // Set each entity state
                // perform SaveChanges
                return (true, null);
            }
            catch (Exception e)
            {
                return (false, e);
            }
        }
    }
    public static class Dialogs
    {
        public static bool Question(string text)
        {
            return (MessageBox.Show(
                text,
                "Question",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Question,
                MessageBoxDefaultButton.Button2) == DialogResult.Yes);
        }
    }
}

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文