Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.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
如何在NHibernate中使用CompositeId级联保存?_Nhibernate_Fluent Nhibernate_Mapping - Fatal编程技术网

如何在NHibernate中使用CompositeId级联保存?

如何在NHibernate中使用CompositeId级联保存?,nhibernate,fluent-nhibernate,mapping,Nhibernate,Fluent Nhibernate,Mapping,我有一个简单的具有多对多关系的三表数据库 A(id, Name) B(id, Name) AB(AId, BId) references A and B 相应的类别: public class A { public virtual int Id { get; set; } public virtual string Name { get; set; } } public class B { public virtual int Id { get; set; }

我有一个简单的具有多对多关系的三表数据库

A(id, Name)
B(id, Name)
AB(AId, BId) references A and B
相应的类别:

public class A
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
}

public class B
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
}

public class AB
{
    public virtual A A { get; set; }
    public virtual B B { get; set; }
    public override bool Equals(object obj) { /* routine */ }
    public override int GetHashCode() { /* routine */ }
}
我已经与Fluent NHibernate进行了映射:

public class AMap : ClassMap<A>
{
    public AMap()
    {
        Id(x => x.Id).GeneratedBy.Identity();
        Map(x => x.Name);
    }
}

public class BMap : ClassMap<B> { /* The same as for A */ }

public class ABMap : ClassMap<AB>
{
    public ABMap()
    {
        CompositeId()
            .KeyReference(x => x.A, "AId")
            .KeyReference(x => x.B, "BId");
    }
}
但在SaveOrUpdate上,我确实得到transientObject异常。因此,要跳过它,我需要在保存AB之前保存或更新A和B。但似乎应该有另一种方法在单个保存或更新中保存这些对象

有没有办法在保存操作时将AB映射指向级联A和B

更新:

为了清晰起见,我删除了一个类中的AB链接列表。原来是:

public class A
{
    public A()
    {
        LinkToB = new List<AB>();
    }

    public virtual int Id { get; set; }
    public virtual string Name { get; set }
    public virtual IList<AB> LinkToB { get; private set; }
}

public class AMap : ClassMap<A>
{
    public AMap()
    {
        Id(x => x.Id).GeneratedBy.Identity();
        Map(x => x.Name);

        HasMany(x => x.LinkToB)
            .KeyColumn("AId")
            .Inverse()
            .Cascade.All()
            .AsBag();
    }
}

// inside the transaction
var a = new A { Name = "a1" };
var b = new B { Name = "b1" };

a.LinkToB.Add(new AB { A = a, B = b });
// session.SaveOrUpdate(b);
session.SaveOrUpdate(a);
公共A类
{
公共A()
{
LinkToB=新列表();
}
公共虚拟整数Id{get;set;}
公共虚拟字符串名称{get;set}
公共虚拟IList LinkToB{get;私有集;}
}
公共类AMap:ClassMap
{
公共AMap()
{
Id(x=>x.Id).GeneratedBy.Identity();
Map(x=>x.Name);
HasMany(x=>x.LinkToB)
.KeyColumn(“援助”)
.Inverse()
.Cascade.All()
.AsBag();
}
}
//交易内部
var a=新的a{Name=“a1”};
var b=新的b{Name=“b1”};
a、 Add(新的AB{a=a,B=B});
//会议.保存或更新(b);
会议.保存或更新(a);

谢谢大家!

只是旁注,但为什么要创建AB类? 如果这两个类之间的关系没有任何额外的属性,那么您的类“AB”是不必要的

回答您的问题:您可以在NHibernate中定义关系的级联选项

在Fluent NHibernate中,我想你必须这样做:

public class FooMap : ClassMap<Foo>
{
    public FooMap()
    {
       HasMany(x => x.Bars).Cascade.AllDeleteOrphan();
    }
}
公共类FooMap:ClassMap
{
公共地图()
{
HasMany(x=>x.bar);
}
}

(请注意,您必须将其应用于您的情况,但是collectionmapping返回一个属性级联,因此您可以定义要应用的级联技术)

我确实在nhibernate用户组问过这个问题。答案是没有办法使用复合id级联任何操作(可能在将来的版本中这是可能的)


所以我做了一个变通办法。我放置了两个引用(多对一级联),而不是CompositeId,并将Id添加到AB表和AB实体中。现在它开始工作了,A和B实体正在级联。

我实际上很容易就让它工作了,代码看起来太不枯燥了

我的案例是这样的:

public class MappingSample : ClassMap<DomainClass>
{
    public MappingCvTheme()
    {
        CompositeId()
            .KeyProperty(x => x.SomeProperty)
            .KeyReference(x => x.SomeReferencedObjectProperty);

        //here comes the trick, repeat the reference code:
        References(x => x.SomeReferencedObjectProperty).Cascade.All();
    }
}
公共类映射示例:类映射
{
公共映射主题()
{
复合ID()
.KeyProperty(x=>x.SomeProperty)
.KeyReference(x=>x.SomeReferencedObjectProperty);
//下面是技巧,重复参考代码:
引用(x=>x.SomeReferencedObjectProperty).Cascade.All();
}
}

我希望它能帮助将来寻找相同问题的人。

感谢您的快速回复。为了简单起见,我删除了这个关系。我应该在哪里输入这个级联规则?我还没有真正使用Fluent,但是当使用xml映射文件时,必须在集合中设置级联属性。在我的情况下,没有办法级联保存操作,或者确实存在?我使用了所有这些技术,但它们只能部分解决问题。示例中的级联来自Foo类(在我的示例中是一个类)。B班呢?如果我将B添加到AB,它将不会级联。示例:
a.Links.add(newab{a=a;B=B})b不会产生一个丑陋的副作用,尽管您将为SomeReferencedObjectProperty创建两列。一个叫做“SomeReferencedObjectPropertyID”,另一个叫做“SomeReferencedObjectProperty”。它们将始终保持同步,但仍然很难看,如果您尝试将KeyReference和References设置为相同的列名,INSERT将失败,因为NH将发送两个参数,尽管只有一列!*在前面的注释中,我假设您正在使用NH创建模式
public class MappingSample : ClassMap<DomainClass>
{
    public MappingCvTheme()
    {
        CompositeId()
            .KeyProperty(x => x.SomeProperty)
            .KeyReference(x => x.SomeReferencedObjectProperty);

        //here comes the trick, repeat the reference code:
        References(x => x.SomeReferencedObjectProperty).Cascade.All();
    }
}