如何将表与winforms控件正确绑定

本文关键字:控件 绑定 winforms | 更新日期: 2023-09-27 18:26:37

我已经把这个问题推迟了一段时间,但现在它一直困扰着我。我有两个类(这些类是自动映射的——为了简洁起见,我省略了publicvirtual。):

class Cashier
{
    int Id {get; set;}
    string name{get; set;}
    IList<Site> Sites {get; set;}
}
class Site
{
    int Id{get; set;}
    string name {get; set;}
    Cashier Cashier {get; set;}
}

我给收银员装上这个:

sealed class Repository<T> : IRepository<T> where T :class
    {
        public IList<T> Items { get; private set; }
        public void Load()
        {
            Items.Clear();
            var session = SessionHelper.GetSession();
            session.Clear();
            using (var tx = session.BeginTransaction())
            {
                var list = session.Query<T>().ToList();
                foreach (var obj in list)
                {
                    Items.Add((T)session.Merge(obj));
                }
                session.Clear();
                tx.Commit();
            }
        }
//more
}

在winform中,我将其绑定到这样的绑定源:

cashierBindingSource.DataSource = Cashiers;

我将此绑定源设置为组合框的数据源,当我运行应用程序并单击组合框时,会向我抛出此异常:

正在初始化[HProject.Model.Cashier#1]-未能延迟初始化角色集合:HRProject.Model_Cashier.Sites,没有会话或会话关闭

我发现提供映射覆盖修复了这个问题

mapping.HasMany(x => x.Sites).Not.LazyLoad().Cascade.All();

然而,我有很多这样的课程,我觉得有一种更干净的方法可以完成这项工作。有什么想法吗?

如何将表与winforms控件正确绑定

根据我的经验,FNH、WinForms数据绑定和延迟加载是一个困难的组合。

如果您需要延迟加载,则需要在表单的生命周期内保持会话打开。

如果你不需要它,你可以把它关掉

对于整个项目,我发现最简单的方法是使用DefaultLazy约定:

.Conventions.Add( DefaultLazy.Never() )

请访问wiki上的"最简单的约定"部分,了解这一点,以及其他内容的列表。

以下是Wiki中的列表:

Table.Is(x => x.EntityType.Name + "Table")
PrimaryKey.Name.Is(x => "ID")
AutoImport.Never()
DefaultAccess.Field()
DefaultCascade.All()
DefaultLazy.Always()
DynamicInsert.AlwaysTrue()
DynamicUpdate.AlwaysTrue()
OptimisticLock.Is(x => x.Dirty())
Cache.Is(x => x.AsReadOnly())
ForeignKey.EndsWith("ID")

警告一下——Wiki中的一些方法名称可能是错误的。我用我可以验证的东西(即DefaultCascade和DefaultLazy)编辑了Wiki,但不能保证其余的。但如果需要,你应该能够用Intellisense找出合适的名称。