简体   繁体   English

使用Fluent NHibernate映射多对多关系,其中关系之一是组件

[英]Mapping a many-to-many relation with Fluent NHibernate where one of the relations is a component

I have the following class tructure. 我有以下课堂结构。

public class SearchTarget : IEntity {
    public virtual String Name { get; set; }
}

public partial class PoliceAssistance {
    public virtual Search SearchWithWarrant { get; set; }
    public virtual Search SearchWithoutWarrant { get; set; }

    public class Search : IEntityComponent {
        public virtual IList<SearchTarget> Targets { get; set; }
    }
}

IEntityComponent ensures that PoliceAssistance.Search is treated as a component in Fluent NHibernate automapping, that is, SearchWithWarrant and SearchWithoutWarrant are stored in the same PoliceAssistance table. IEntityComponent确保将PoliceAssistance.Search视为Fluent NHibernate自动映射中的一个组件,即SearchWithWarrantSearchWithoutWarrant存储在同一PoliceAssistance表中。

The problem 问题

PoliceAssistance.Search.Targets and SearchTarget must have a many-to-many relationship — one search can contain many targets and one target can show up in many searches. PoliceAssistance.Search.TargetsSearchTarget必须具有多对多关系-一个搜索可以包含许多目标,而一个目标可以出现在许多搜索中。

If I specify unidirectional .HasManyToMany() mapping on PoliceAssistance.Search , I get a "null value violates non-null constraint" when I try to save the entities — even if both SearchWithWarrant and SearchWithoutWarrant are instantiated and have at least one Target in the list. 如果我在PoliceAssistance.Search上指定单向.HasManyToMany()映射, PoliceAssistance.Search在尝试保存实体时会收到“空值违反非空约束”的信息,即使同时实例化SearchWithWarrantSearchWithoutWarrant并在其中至少有一个Target清单。

If I try to specify the mapping bidirectionally, by introducing public virtual IList<PoliceAssistance.Search> InSearches { get; set; } 如果我尝试双向指定映射,请通过引入public virtual IList<PoliceAssistance.Search> InSearches { get; set; } public virtual IList<PoliceAssistance.Search> InSearches { get; set; } public virtual IList<PoliceAssistance.Search> InSearches { get; set; } property into SearchTarget and mapping it with .HasManyToMany().Inverse() , I get a mapping error saying that PoliceAssistance.Search cannot be referenced because it is not mapped (I guess types mapped as components aren't considered mapped?). public virtual IList<PoliceAssistance.Search> InSearches { get; set; }属性转换为SearchTarget并使用.HasManyToMany().Inverse()进行映射,我收到一个映射错误, PoliceAssistance.Search无法引用PoliceAssistance.Search因为它没有被映射(我猜映射为组件的类型不被认为是映射的?)。

How should I solve this problem? 我应该如何解决这个问题?

I don't know anything about the Fluent NHibernate engine but a many-to-many connection is always made with a link-table/object. 我对Fluent NHibernate引擎一无所知,但总是使用链接表/对象建立多对多连接。 So I would expect that you would have something like this: 因此,我希望您会有这样的事情:

public class SearchTarget : IEntity
{
    public virtual String Name { get; set; }
    public virtual IList<Search_SearchTarget_Link> Searches { get; set; }
}

public class Search : IEntityComponent
{
    public virtual IList<Search_SearchTarget_Link> Targets { get; set; }
}

public class Search_SearchTarget_Link : IEntity
{
    public virtual Search search { get; set; }
    public virtual SearchTarget searchtarget { get; set; }
}

public partial class PoliceAssistance
{
    public virtual Search SearchWithWarrant { get; set; }
    public virtual Search SearchWithoutWarrant { get; set; }
}

Hope this helps... 希望这可以帮助...

After fighting with this some more, I gave up on trying to get the mapping working with PoliceAssistance.Search as component, and instead turned it into a separate entity. 经过更多的努力之后,我放弃了尝试使该映射与PoliceAssistance.Search作为组件一起工作,而是将其变成一个单独的实体。 This required least amount of changes and works as expected: 这需要最少的更改,并且可以按预期工作:

// Classes
public class SearchTarget : IEntity {
    public virtual String Name { get; set; }
}

public partial class PoliceAssistance {
    public virtual Search SearchWithWarrant { get; set; }
    public virtual Search SearchWithoutWarrant { get; set; }

    public class Search : IEntity {
        public virtual int Id { get; set; }
        public virtual IList<SearchTarget> Targets { get; set; }
    }
}

// Mapping
public class PoliceAssistanceMap : IAutoMappingOverride<PoliceAssistance> {
    public void Override(AutoMapping<PoliceAssistance> map) {
        map.References(x => x.SearchWithWarrant)
           .Cascade.All();
        map.References(x => x.SearchWithoutWarrant)
           .Cascade.All();
    }
}

public class SearchMap : IAutoMappingOverride<PoliceAssistance.Search> {
    public void Override(AutoMapping<PoliceAssistance.Search> mapping) {
        mapping.HasManyToMany(x => x.Targets);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM