简体   繁体   English

c# winform,对象不能从dbnull转换为其他类型

[英]c# winform, object cannot be cast from dbnull to other types

I have checkbox in my DataGridView to delete one or multiple rows from my DataGridView already loaded data from database.我的 DataGridView 中有复选框,可以从我的 DataGridView 中删除一行或多行已经从数据库加载的数据。 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".但我收到此错误“对象无法从 dbnull 转换为其他类型”。 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;
            }
        }
        
    }

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.以下是使用 Entity Framework Core 和 C#9 的模式,如果使用 .NET Framework 4.8,则需要进行一些调整,但原理与下文所述相同。

Model Categories where Checked property is not part of the underlying table. Checked属性不属于基础表的模型Categories [NotMapped] tells Entity Framework to exclude this property while [DefaultValue(false)] provides false as the default value. [NotMapped]告诉 Entity Framework 排除此属性,而[DefaultValue(false)]提供 false 作为默认值。

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.在表单中,创建一个用于所有操作的BindingSource ,一旦将其作为 DataSource 分配给 DataGridView。 As mentioned in various comments, there is zero need to reference data via the DataGridView.正如各种评论中提到的,通过 DataGridView 引用数据的需求为零。

Notes笔记

  • Code is C#9, minor adjustments will be needed if not using .NET Core.代码为 C#9,如果不使用 .NET Core,则需要稍作调整。
  • In the button to remove records a lambda statement is used to get checked items在删除记录的按钮中,一个 lambda 语句用于获取检查项目
  • A wrapper for MessageDialog is used to ask permission to remove data MessageDialog 的包装器用于请求删除数据的权限
  • 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 DataGridView 列是在 DataGridView 设计器中创建的,并且每列 DataPropertyName 设置为模型中的属性

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($"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);
        }
    }
}

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM