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

时间:2011-03-20 10:02:48

标签: c# .net winforms nhibernate datagridview

我遇到的问题无法解决问题。

我正在绑定DataGridView并在运行时创建我的列。文本列没有问题,但我的下拉有问题,特别是我得到一个System.FormatException。我绑定了一个List<>到从数据库中检索的datagridview。

网格视图的数据源结构如下:
- 产品ID
- 评论
- 姓名
- 品牌: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

我哪里错了?它让我疯了,当我捕获异常时它显示正常 - 但显然,我不想因为某处存在问题而捕获异常。

我唯一能想到的是NHibernate在某种程度上会导致问题吗?

3 个答案:

答案 0 :(得分:1)

我不确定下面的答案是否与您遇到的例外情况直接相关,但我相信这会给您带来很多麻烦。

简短回答

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

答案很长

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

答案 1 :(得分:1)

正如埃蒂所指出的,这肯定是一个懒惰的装载问题。当您获取产品并启用延迟加载(默认设置)时,您将获得所有产品,但只获得品牌的ID。然后,当您在datagridview中显示产品列表时,nhibernate正在尝试加载品牌名称。当您关闭会话对象时,它无法延迟加载品牌实体,因此您会收到错误。我强烈建议你看一下ASP.Net MVC。它有一个更清晰的模型来处理ORM(但是,你失去了所有花哨的控件绑定)。如果你不能或不想,你有三个选择:

  1. 禁用延迟加载(出于性能原因非常糟糕)
  2. 在您进行查询时,您需要根据需要加载实体(SetFetchMode(“Brand”,FetchMode.Join),NHibernateUtil.Initialize等。)
  3. 准备一个viewmodel对象,其中包含所有加载的实体,并将其发送到您的aspx页面。

答案 2 :(得分:1)

简答,是的可能!!我在我的Nhiberante模型中创建了一个只有Get Property

的属性
    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);
    }
}

然后我调用此属性来填充DatagridView中的ComboBox

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;

我希望我帮助你!!