C# Fluent Nhibernate具有非主键的一对一映射

C# Fluent Nhibernate具有非主键的一对一映射,c#,nhibernate,fluent-nhibernate,nhibernate-mapping,one-to-one,C#,Nhibernate,Fluent Nhibernate,Nhibernate Mapping,One To One,无法找出下表的正确映射 Table: ItemSale {ItemCode, SaleDate, Qty, SaleCode} ItemCode and SaleDate are composite key. SaleCode is a derived column, generated from the combination of ItemCode and SaleDate column. Table: ItemSaleDetail

无法找出下表的正确映射

  Table: ItemSale    {ItemCode, SaleDate, Qty, SaleCode}  
         ItemCode and SaleDate are composite key.
         SaleCode is a derived column, generated from the combination of ItemCode and SaleDate column. 

  Table: ItemSaleDetail {SaleCode, Agent}
         SaleCode is a primary key and foreign key from ItemSale table for SaleCode column.
实体及其映射如下所示。

商品销售

public class ItemSale
{
    public virtual string ItemCode { get; set; }
    public virtual string Date { get; set; }
    public virtual string  SaleCode { get; set; }
    public virtual ItemSaleDetail SaleDetail { get; set; }
}

public class ItemSaleMap : ClassMap<ItemSale>
{
    public ItemSaleMap()
    {
        Table("ItemSale");
        CompositeId()
          .KeyReference(x => x.ItemCode, "ItemCode")
          .KeyProperty(x => x.Date, "SaleDate");
        HasOne(x => x.SaleDetail).Cascade.All();
    }
}
公共类物品销售
{
公共虚拟字符串ItemCode{get;set;}
公共虚拟字符串日期{get;set;}
公共虚拟字符串SaleCode{get;set;}
公共虚拟项SaleDetail SaleDetail{get;set;}
}
公共类ItemSaleMap:ClassMap
{
public ItemSaleMap()
{
表(“项目销售”);
复合ID()
.KeyReference(x=>x.ItemCode,“ItemCode”)
.KeyProperty(x=>x.Date,“SaleDate”);
HasOne(x=>x.SaleDetail).Cascade.All();
}
}
商品详细信息

public class ItemSaleDetail
{
    public virtual string ItemSaleCode { get; set; }
    public virtual string Agent { get; set; }
    public virtual ItemSale SaleParent { get; set; }

}

public class ItemSaleDetailMap : ClassMap<ItemSaleDetail>
{
    public ItemSaleDetailMap()
    {
        Table("ItemSaleDetail");
        Id(x => x.ItemSaleCode).GeneratedBy.Foreign("SaleParent");
        Map(x => x.Agent, "Agent");
        HasOne(x => x.SaleParent).Constrained(); 
    }
}
公共类ItemSaleDetail
{
公共虚拟字符串ItemSaleCode{get;set;}
公共虚拟字符串代理{get;set;}
公共虚拟项父项{get;set;}
}
公共类ItemSaleDetailMap:ClassMap
{
public itemsaletailmap()
{
表(“详细项目”);
Id(x=>x.ItemSaleCode).GeneratedBy.Foreign(“SaleParent”);
地图(x=>x.代理,“代理”);
HasOne(x=>x.SaleParent).Constrained();
}
}
我在上面给出了以传统方式使用的基本一对一映射,我知道这在本例中是错误的。 在这种情况下,请建议如何提供正确的映射。
另外,如果应用程序要生成派生列代码,我们如何在我的实体中拥有此属性。因为不允许对单个列进行多个映射

好的,使用可分配ID,我们可以这样做。首先,我们应该确保ID已分配,因此我们可以调整
ItemSaleCode
的getter,如下所示:

public class ItemSaleDetail
{
    string _itemSaleCode;

    public virtual string ItemSaleCode
    {
        get { return _itemSaleCode ?? SaleParent.SaleCode ; }
        set { _itemSaleCode  = value; }
    }
<id name="ItemSaleCode" column="SaleCode" type="String" generator="assigned" />
<one-to-one name="SaleParent" class="ItemSale"
    constrained="true" property-ref="SaleCode" />
...
public ItemSaleDetailMap()
{
    ...
    Id(x => x.ItemSaleCode)
        .CustomType<String>()
        .Column("SaleCode")
        .GeneratedBy.Assigned();

    HasOne(x => x.SaleParent)
       .ProeprtyRef("SaleCode")
       .Constrained(); 
}


public ItemSaleMap()
{
    References(x => x.SaleDetail)
       .Column("SaleCode")
       .Unique()
       .Cascade.All();
    Map(x => x.SaleCode)
       .Column("SaleCode")
       .Not.Update()
       .Not.Insert()
}
现在,我们需要这样的映射:

public class ItemSaleDetail
{
    string _itemSaleCode;

    public virtual string ItemSaleCode
    {
        get { return _itemSaleCode ?? SaleParent.SaleCode ; }
        set { _itemSaleCode  = value; }
    }
<id name="ItemSaleCode" column="SaleCode" type="String" generator="assigned" />
<one-to-one name="SaleParent" class="ItemSale"
    constrained="true" property-ref="SaleCode" />
...
public ItemSaleDetailMap()
{
    ...
    Id(x => x.ItemSaleCode)
        .CustomType<String>()
        .Column("SaleCode")
        .GeneratedBy.Assigned();

    HasOne(x => x.SaleParent)
       .ProeprtyRef("SaleCode")
       .Constrained(); 
}


public ItemSaleMap()
{
    References(x => x.SaleDetail)
       .Column("SaleCode")
       .Unique()
       .Cascade.All();
    Map(x => x.SaleCode)
       .Column("SaleCode")
       .Not.Update()
       .Not.Insert()
}


...
...

在Fluent中应该是这样的:

public class ItemSaleDetail
{
    string _itemSaleCode;

    public virtual string ItemSaleCode
    {
        get { return _itemSaleCode ?? SaleParent.SaleCode ; }
        set { _itemSaleCode  = value; }
    }
<id name="ItemSaleCode" column="SaleCode" type="String" generator="assigned" />
<one-to-one name="SaleParent" class="ItemSale"
    constrained="true" property-ref="SaleCode" />
...
public ItemSaleDetailMap()
{
    ...
    Id(x => x.ItemSaleCode)
        .CustomType<String>()
        .Column("SaleCode")
        .GeneratedBy.Assigned();

    HasOne(x => x.SaleParent)
       .ProeprtyRef("SaleCode")
       .Constrained(); 
}


public ItemSaleMap()
{
    References(x => x.SaleDetail)
       .Column("SaleCode")
       .Unique()
       .Cascade.All();
    Map(x => x.SaleCode)
       .Column("SaleCode")
       .Not.Update()
       .Not.Insert()
}
public itemsaletailmap()
{
...
Id(x=>x.ItemSaleCode)
.CustomType()
.栏(“销售代码”)
.GeneratedBy.Assigned();
HasOne(x=>x.SaleParent)
.ProeprtyRef(“销售代码”)
.constrated();
}
public ItemSaleMap()
{
参考(x=>x.SaleDetail)
.栏(“销售代码”)
.Unique()
.Cascade.All();
映射(x=>x.SaleCode)
.栏(“销售代码”)
.Not.Update()
.Not.Insert()
}

但是,我可以肯定的是,代理INT或LONG键的方式…

您的表和实体非常复杂。如果你的领域模型很复杂,你应该开始重新思考它。我的建议是:尽量让实体具有ID(生成的,没有任何业务价值)。例如,
Long
int
。。。所有的映射都将变得更容易,您将从NHibernate等工具中获得更多。如果您认为您当前的内容是最好的,我至少建议使用
SaleCode
列作为键(字符串)。这将通过一对一解决您的问题…但是,请考虑代理密钥。感谢Radim提供您的快速建议。如果我将ItemSaleCode更改为GeneratedBy.Assigned from GeneratedBy.Foreign(“SaleParent”)。很高兴见到您,先生;),请您再次建议如何进行映射强大的尼伯酸盐;)如果ItemSaleDetail有一个主代理键,但ItemSale使用SaleCode,这可能吗?