Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# NHibernate:保存临时实例时如何更新标识Id?_C#_.net_Database_Nhibernate_Fluent Nhibernate - Fatal编程技术网

C# NHibernate:保存临时实例时如何更新标识Id?

C# NHibernate:保存临时实例时如何更新标识Id?,c#,.net,database,nhibernate,fluent-nhibernate,C#,.net,Database,Nhibernate,Fluent Nhibernate,如果我使用每个事务的会话并调用: 会话。保存或更新(实体)更正: 会话。保存或更新副本(实体) ..实体是标识Id为0的临时实例。上述行是否应自动更新实体的Id,并使实例持久化?或者它应该在transaction.Commit上这样做?还是我必须以某种方式显式地编写代码 显然,数据库行的Id(新的,因为是暂时的)是自动生成的,并保存为某个数字,但我在这里讨论的是实际的参数实例。这是业务逻辑实例 编辑-跟进相关问题 映射: public class StoreMap : ClassMap<

如果我使用每个事务的会话并调用:

会话。保存或更新(实体)更正:
会话。保存或更新副本(实体)

..实体是标识Id为0的临时实例。上述行是否应自动更新实体的Id,并使实例持久化?或者它应该在transaction.Commit上这样做?还是我必须以某种方式显式地编写代码

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


编辑-跟进相关问题

映射:

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");
     } 
}
   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; }
}
公共类存储映射:类映射
{
公共存储地图()
{
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()
.表格(“存储产品”);
}
}
公共类EmployeeMap:ClassMap
{
公共雇员地图()
{
Id(x=>x.Id).GeneratedBy.Identity();
Map(x=>x.FirstName);
Map(x=>x.LastName);
引用(x=>x.Store);//m:1
}
}
公共类ProductMap:ClassMap
{
公共产品地图()
{
Id(x=>x.Id).GeneratedBy.Identity();
Map(x=>x.Name).Length(20);
地图(x=>x.Price).CustomSqlType(“十进制”).Precision(9).Scale(2);
HasManyToMany(x=>x.StoresStockedIn)
.Cascade.All()
.Inverse()
.表格(“存储产品”);
} 
}

EDIT2

类定义:

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");
     } 
}
   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; }
}
公共类存储
{
public int Id{get;private set;}
公共字符串名称{get;set;}
公共IList产品{get;set;}
公共IList职员{get;set;}
公共商店()
{
产品=新列表();
职员=新名单();
}
//AddProduct和AddEmployee是必需的。“NH需要您在
//它将正确保存“
公共产品(产品)
{
product.StoresStockedIn.Add(此);
产品。添加(产品);
}
公共无效添加员工(员工)
{
employee.Store=this;
Staff.Add(雇员);
}
}
公营雇员
{
public int Id{get;private set;}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共存储{get;set;}
}
公共类产品
{
public int Id{get;private set;}
公共字符串名称{get;set;}
公共十进制价格{get;set;}
公共IList存储stockedin{get;private set;}
}

我不太明白你的问题。在刷新会话时(例如,通过提交事务),将实际保存到数据库。调用SaveOrUpdate()本身并不保存实体,它只是通知会话在刷新会话时将保存实体


假设实体的ID映射到数据库中的标识字段,并且映射告诉NHibernate该标识是由数据库设置的,则数据库设置的ID将在保存时设置为实体的ID。

NHibernate将在SaveOrUpdate调用之后设置实体的ID属性

我注意到我通过打电话保存了:

session.SaveOrUpdateCopy(entity); 
..不更新Id,但通过更改为:

session.SaveOrUpdate(entity);
..将更新瞬态实体的Id

我可能误解了这句话:

SaveOrUpdateCopy(对象o)。。。如果给定实例未保存或不存在于数据库中,NHibernate将保存该实例并将其作为新的持久实例返回。


它只是我,还是听起来不像是一个临时对象(未保存),将“作为持久对象返回”?这不意味着更新了身份证吗?请澄清如何正确解释这句话(?)

就您的问题而言,无论何时刷新会话,都是在实体持久化到数据库时。保存(新)实体时,NHibernate使用您提供的生成器为您生成ID

请记住,不建议使用标识生成器(请参阅)。 使用标识生成器时,即使未刷新到数据库,在保存时也会将新实体持久化到数据库。发生这种情况的原因是,NHibernate需要为您提供实体的ID,如果不来回访问数据库,它就无法做到这一点


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

是的,您的意思是;在代码行transaction.Commit()之后,实体的Id属性应反映数据库行的设置?我询问的原因是我跟踪代码(在我的repository.SaveOrUpdate方法中),实体的id始终为0,即使在.Commit之后也是如此。所以我想确认应该在什么时候设置。如果提交后您的id为0,则表明您没有正确映射生成器。谢谢!这很好,得到了坚定的证实。那一定和我的另一个问题有关。我想这个身份证问题可能是那个问题的原因。但我认为这是一种结果,而不是原因。顺便提一下“生成器”是指标准的实体类映射吗?或ISessionFactory配置?更改Id(x=>x.Id);到Id(x=>x.Id).GeneratedBy.Identity();我这样做了(认为它是默认自动生成的,但不确定)。但是它仍然没有更新entity-Id。我想这是有道理的,因为会话范围可能很长。但我的Id仍然是0..FluentNHibernate根据OP的标签判断。正常