C# 将结果绑定到带有NHibernate组合框的DataGridView是否存在问题

C# 将结果绑定到带有NHibernate组合框的DataGridView是否存在问题,c#,.net,winforms,nhibernate,datagridview,C#,.net,Winforms,Nhibernate,Datagridview,我有一些问题,我无法解决这个问题 我正在绑定DataGridView并在运行时创建列。文本列可以正常工作,但是我的下拉列表有问题,特别是我遇到了System.FormatException。我正在将一个列表绑定到从数据库检索的datagridview 网格视图的数据源的结构如下: -ProductID -评论 -名称 -品牌:IBrand -制造商:IBrand IBrand的结构如下: -ID -名字 创建列时,我使用以下代码: DataGridViewComboBoxColumn colum

我有一些问题,我无法解决这个问题

我正在绑定DataGridView并在运行时创建列。文本列可以正常工作,但是我的下拉列表有问题,特别是我遇到了System.FormatException。我正在将一个列表绑定到从数据库检索的datagridview

网格视图的数据源的结构如下:
-ProductID
-评论
-名称
-品牌:IBrand
-制造商:IBrand

IBrand的结构如下:
-ID
-名字

创建列时,我使用以下代码:

DataGridViewComboBoxColumn column = new DataGridViewComboBoxColumn();

column.DisplayMember = "Name";
column.ValueMember = "ID";
column.DataPropertyName = "Manufacturer";
column.ValueType = typeof(IBrand);
column.DataSource = [List<> of IBrand], returned from NHibernate
DataGridViewComboxColumn=newDataGridViewComboxColumn();
column.DisplayMember=“Name”;
column.ValueMember=“ID”;
column.DataPropertyName=“制造商”;
column.ValueType=类型(IBrand);
column.DataSource=[IBrand列表],从NHibernate返回
我哪里做错了?这让我发疯,当我捕获异常时,它显示得很好——但是很明显,我不想捕获异常,因为在某个地方存在问题


我能想到的唯一一件事是,NHibernate在某种程度上导致了这里的问题?

我不确定下面的答案是否与您遇到的异常直接相关,但我相信这将为您省去很多麻烦

简短回答 您不应该将nhibernate返回的对象绑定到UI。将它们投影到DTO或ViewModel对象,并将它们绑定到UI

长话短说
NHibernate是一种ORM,旨在将域对象(构成业务逻辑的互连对象的孔图)映射到关系数据库持久存储。为了能够做到这一点,NHibernate使用延迟加载来避免将所有对象图加载到内存中。要执行延迟加载,NHibernate使用从类继承的生成的代理,这些代理来自它们代理的类。不建议将代理绑定到UI,因为代理需要ISession仍然处于活动状态才能执行延迟加载。

我不确定下面的答案是否与您遇到的异常直接相关,但我相信这将为您省去很多麻烦

简短回答 您不应该将nhibernate返回的对象绑定到UI。将它们投影到DTO或ViewModel对象,并将它们绑定到UI

长话短说
NHibernate是一种ORM,旨在将域对象(构成业务逻辑的互连对象的孔图)映射到关系数据库持久存储。为了能够做到这一点,NHibernate使用延迟加载来避免将所有对象图加载到内存中。要执行延迟加载,NHibernate使用从类继承的生成的代理,这些代理来自它们代理的类。不建议将代理绑定到UI,因为代理需要ISession仍然处于活动状态才能执行延迟加载。

正如eti指出的,这肯定是延迟加载问题。当您获取产品并启用延迟加载(默认设置)时,您将获取所有产品,但仅获取品牌id。然后,当您在datagridview中显示产品列表时,nhibernate正在尝试加载品牌名称。由于您已经关闭了会话对象,它无法延迟加载品牌实体,因此您会返回一个错误。我强烈建议您看看ASP.NETMVC。它有一个更简洁的模型来处理ORMs(但是,是的,你会失去所有的控件绑定)。如果您不能或不想,您有三个选择:

  • 禁用延迟加载(出于性能原因,这是一个非常糟糕的主意)
  • 当您进行查询时(SetFetchMode(“Brand”、FetchMode.Join)、NHibernateUtil.Initialize等),您可以根据需要加载实体
  • 准备一个viewmodel对象,并加载所有实体,然后将其发送到您的aspx页面

  • 正如eti指出的,这肯定是一个延迟加载问题。当您获取产品并启用延迟加载(默认设置)时,您将获取所有产品,但仅获取品牌id。然后,当您在datagridview中显示产品列表时,nhibernate正在尝试加载品牌名称。由于您已经关闭了会话对象,它无法延迟加载品牌实体,因此您会返回一个错误。我强烈建议您看看ASP.NETMVC。它有一个更简洁的模型来处理ORMs(但是,是的,你会失去所有的控件绑定)。如果您不能或不想,您有三个选择:

  • 禁用延迟加载(出于性能原因,这是一个非常糟糕的主意)
  • 当您进行查询时(SetFetchMode(“Brand”、FetchMode.Join)、NHibernateUtil.Initialize等),您可以根据需要加载实体
  • 准备一个viewmodel对象,并加载所有实体,然后将其发送到您的aspx页面

  • 简而言之,是的,这是可能的!!。我在我的Nhiberante模型中创建了一个属性,只有Get属性

        public virtual Area Area { get; set; }
        public virtual string Nome { get; set; }
        public virtual string Descricao { get; set; }
        public virtual bool IsActive { get; set; }
    
        public virtual int Area_Id
        {
            get { return this.Area != null ? Area.Id : 0; }
        }
    
    我的属性Area_Id是一个Calculate属性,我没有在FluentMapping中映射此字段

    public class CargoMapping : ClassMap<Cargo>
    {
        public CargoMapping()
        {
            this.Id(x => x.Id);
            this.Map(x => x.Nome);
            this.Map(x => x.Descricao);
            this.Map(x => x.IsActive);
            this.References(x => x.Area);
        }
    }
    
    公共类映射:类映射
    {
    公共货物测绘()
    {
    this.Id(x=>x.Id);
    这个.Map(x=>x.Nome);
    this.Map(x=>x.descripcao);
    this.Map(x=>x.IsActive);
    这是参考(x=>x.Area);
    }
    }
    
    然后我调用这个属性来填充DatagridView中的组合框

    DataGridViewComboBoxColumn dtgViewColumn = new DataGridViewComboBoxColumn();
                    dtgViewColumn.DataPropertyName = "Area_Id";
                    dtgViewColumn.HeaderText = "Area";
                    dtgViewColumn.Width = 120;
                    dtgViewColumn.DataSource = db.GetActive<Area>();
                    dtgViewColumn.ValueMember = "Id";
                    dtgViewColumn.DisplayMember = "Nome";
    
                    this.StarkDataGridView.Columns.Add(dtgViewColumn);
                    this.StarkDataGridView.ReadOnly = false;
                    this.StarkDataGridView.Columns["Id"].ReadOnly = true;
                    this.StarkDataGridView.AutoGenerateColumns = false;
                    this.StarkDataGridView.Columns["Id"].DisplayIndex = 0;
                    this.StarkDataGridView.Columns["Nome"].DisplayIndex = 1;
                    this.StarkDataGridView.Columns["Descricao"].DisplayIndex = 3;
                    this.StarkDataGridView.Columns["IsActive"].DisplayIndex = 4;
                    this.StarkDataGridView.Columns["IsActive"].HeaderCell.Value = "Ativo";
                    this.StarkDataGridView.Columns["Delete"].DisplayIndex = 5;
                    this.StarkDataGridView.Columns["Area"].Visible= false;
                    this.StarkDataGridView.Columns["Area_Id"].Visible = false;
    
    DataGridViewComboxColumn dtgViewColumn=new DataGridViewComboxColumn();
    dtgViewColumn.DataPropertyName=“区域Id”;
    dtgViewColumn.HeaderText=“区域”;
    dtgViewColumn.Width=120;
    dtgViewColumn.DataSource=db.GetActive();
    dtgViewColumn.ValueMember=“Id”;
    dtgViewColumn.DisplayMember=“Nome”;
    this.StarkDataGridView.Columns.Add(dtgViewColumn);
    this.StarkDataGridView.ReadOnly=false;
    这是StarkDataGri