c# - NHibernate:保存 transient 实例时如何更新身份标识?

标签 c# .net database nhibernate fluent-nhibernate

如果我使用 session-per-transaction 并调用:

session.SaveOrUpdate(entity) 更正:
session.SaveOrUpdateCopy(实体)

..and entity 是一个 identity-Id=0 的临时实例。上面的行是否应该自动更新实体的 Id,并使实例持久化?或者它应该在 transaction.Commit 上这样做吗?还是我必须以某种方式显式编码?

显然数据库行的 Id(新的,因为是 transient 的)是自动生成的并保存为一些数字,但我在这里谈论的是实际参数实例。这是业务逻辑实例。


编辑 - 相关问题的跟进。

映射:

public class StoreMap : ClassMap<Store>
{
    public StoreMap()
    {
        Id(x => x.Id).GeneratedBy.Identity();
        Map(x =>  x.Name);
        HasMany(x => x.Staff)    // 1:m
            .Cascade.All();       
        HasManyToMany(x => x.Products)  // m:m
            .Cascade.All()
            .Table("StoreProduct");    
    }
}

public class EmployeeMap : ClassMap<Employee> 
{
    public EmployeeMap()
    {
        Id(x => x.Id).GeneratedBy.Identity();   
        Map(x => x.FirstName);
        Map(x => x.LastName);
        References(x => x.Store);    // m:1
    }
}

public class ProductMap : ClassMap<Product>
{
    public ProductMap() 
    {
        Id(x => x.Id).GeneratedBy.Identity();
        Map(x => x.Name).Length(20);
        Map(x => x.Price).CustomSqlType("decimal").Precision(9).Scale(2);
        HasManyToMany(x => x.StoresStockedIn)
        .Cascade.All()
        .Inverse()
        .Table("StoreProduct");
     } 
}

EDIT2

类定义:

   public class Store
{
    public int Id { get; private set; }
    public string Name { get; set; }
    public IList<Product> Products { get; set; }
    public IList<Employee> Staff { get; set; }

    public Store()
    {
        Products = new List<Product>();
        Staff = new List<Employee>();
    }


    // AddProduct & AddEmployee is required. "NH needs you to set both sides before
    // it will save correctly" 

    public void AddProduct(Product product)
    {
        product.StoresStockedIn.Add(this);
        Products.Add(product);
    }

    public void AddEmployee(Employee employee)
    {
        employee.Store = this;
        Staff.Add(employee);
    }
}

public class Employee
{
    public int Id { get;  private set; }
    public string FirstName { get;  set; }
    public string LastName { get;  set; }
    public Store Store { get; set; }
}

public class Product
{
    public int Id { get; private set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public IList<Store> StoresStockedIn { get; private set; }
}

最佳答案

就您的问题而言,每当您刷新 session 时,您的实体就会持久保存到数据库中。保存您的(新)实体时,NHibernate 会使用您提供的生成器为您生成 ID。

请记住,不推荐使用身份生成器(参见 this post by Ayende )。 当您使用身份生成器时,即使您没有刷新到数据库,您的新实体也会在您保存时持久保存到数据库中。发生这种情况的原因是因为 NHibernate 需要为您提供实体的 ID,如果不往返数据库就无法做到这一点。

更好的解决方案是使用 Guid 生成器之类的东西,或者如果您想要“正常”值,则使用 HiLo。通过这种方式,您可以保存您的实体而无需实际执行数据库往返,这使您可以在性能方面做得更多(想到批处理)。

关于c# - NHibernate:保存 transient 实例时如何更新身份标识?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4896001/

相关文章:

mysql - 2 非常快速和简单的查询合并在一起时非常慢

SQL Server - 如何在我的表上查找依赖表?

sql - 为防止插入的sqlite数据库创建触发器

c# - 蓝牙扫描C#

c# - HashSet<int> 和 List<int> 的快速交集

.net - 为什么在 .Net 中使用异步编程模型不会导致 StackOverflow 异常?

.net - 使用相同的 key 对多个程序集进行签名 : wise/unwise?

c# - 确保派生进程的窗口位于主应用程序的前面?

c# - 通过资源将 Python 嵌入到 C# 中

c# - 我如何解决 "Please make sure that the file is accessible and that it is a valid assembly or COM component"?