简体   繁体   English

流利的NHibernate映射帮助使用CompositeID引用静态视图

[英]Fluent NHibernate Mapping Help static view referencing with compositeID

Afternoon all. 下午全部。 I'm trying to create a mapping for a flight segment database where at the bottom of the mapping tree a FlightSegment references an origin and destination table with a compositeID consisting of a three letter code and a Boolean determining whether the code is or isn't a city. 我正在尝试为航班段数据库创建一个映射,其中在映射树的底部,FlightSegment引用了一个起始和目的地表,该起始和目的地表的CompositeID由三个字母代码和一个布尔值组成,该布尔值确定该代码是否为一座城市。

Below are the relevant simplified class structures: 以下是相关的简化类结构:

    public class GTIFlightSegment
        {
            public virtual int ID { get; protected set; }


            public virtual GTIOriginAirport Origin { get; set; }
            public virtual GTIDestinationAirport Destination { get; set; }

            public virtual GTIFlightSegmentGroup Parent { get; set; }

        }

  public class GTIAirport
    {

        public virtual string Code { get; set; }
        public virtual string Name { get; set; }
        public virtual  string City { get; set; }
        public virtual string CountryCode { get; set; }
        public virtual GTIGeoCode GeoCode {get; set; }
        public virtual string Terminal { get; set; }
        public virtual bool IsCity { get; set; }
        public GTIAirport()
        {
            GeoCode = new GTIGeoCode();
            IsCity = false;
        }

        public override bool Equals(object obj)
        {
            var other = obj as GTIAirport;

            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;

            return this.Code == other.Code && this.IsCity == other.IsCity;
        }


        public override int GetHashCode()
        {
            unchecked
            {
                int hash = GetType().GetHashCode();
                hash = (hash * 31) ^ Code.GetHashCode();
                hash = (hash * 31) ^ IsCity.GetHashCode();

                return hash;
            }
        }

    }

    public class GTIOriginAirport : GTIAirport
    {
        public virtual GTIFlightSegment Parent { get; set; }

        public GTIOriginAirport() : base()
        {

        }
    }

    public class GTIDestinationAirport : GTIAirport
    {

        public virtual GTIFlightSegment Parent { get; set; }

        public GTIDestinationAirport() : base()
        {

        }
    }

And below are the mappings I've created so far for the objects: 下面是我到目前为止为对象创建的映射:

public class GTIFlightSegmentMap : ClassMap<GTIFlightSegment>
    {
        public GTIFlightSegmentMap()
        {
            Id(x => x.ID);

            References(x => x.Destination).Columns(new string[] { "DestinationCODE", "DestinationIsCity" }).Cascade.All();
            References(x => x.Origin).Columns(new string[] { "OriginCODE", "OriginIsCity"}).Cascade.All();

            References(x => x.Parent).Not.Nullable();


        }
    }


 public class GTIAirportMap : ClassMap<GTIAirport>
    {
        public GTIAirportMap()
        {
            Table("GTIAirport");
            ReadOnly();
            CompositeId()
                .KeyProperty(x => x.Code, "CODE")
                .KeyProperty(x => x.IsCity, "isCity");                 

            Map(x => x.Name).Column("Airport");
            Map(x => x.City);
            Map(x => x.CountryCode);
            Component(x => x.GeoCode, m =>
            {
                m.Map(x => x.Latitude);
                m.Map(x => x.Longitude);

            });

        }

    }

    public class GTIOriginAirportMap : SubclassMap<GTIOriginAirport>
    {
        public GTIOriginAirportMap()
        {
            KeyColumn("CODE");
            KeyColumn("isCity");
            HasOne(x => x.Parent).PropertyRef(x => x.Origin);
        }
    }


    public class GTIDestinationAirportMap : SubclassMap<GTIDestinationAirport>
    {
        public GTIDestinationAirportMap()
        {
            KeyColumn("CODE");
            KeyColumn("isCity");
            HasOne(x => x.Parent).PropertyRef(x => x.Origin);
        }
    }

What I'm trying to achieve is that when a FlightSegment is created in the system it will store the DestinationIsCity/DestinationCode and the OriginIsCity/OriginCode in the flight segments table but not try and update the GTIAirport reference table view. 我要实现的目标是,在系统中创建FlightSegment时,它将在航班段表中存储DestinationIsCity / DestinationCode和OriginIsCity / OriginCode,但不会尝试更新GTIAirport参考表视图。 But when the objects are retrieved from the database with a query over, the rich information from the GTIAirport reference table will be fetched. 但是,如果通过查询从数据库中检索到对象,则会从GTIAirport参考表中获取丰富的信息。

Or possibly have the Code and IsCity in the DepartureAirport and OriginAirport tables respectively with a ID reference back to the flight segment. 或者,可能在DepartureAirport和OriginAirport表中分别包含Code和IsCity,且ID参考返回到该航段。

No matter what connotations I'm trying I'm hitting a wall of some kind. 无论我尝试什么涵义,我都在碰壁。 Basically I've got myself in a bit of a mess. 基本上,我有点混乱。 I've flipped the relationships between the Airport and segment, swapping out to only references. 我已经翻转了机场和路段之间的关系,只交换了参考。 Cascaded, not cascaded. 级联,而不是级联。

Common Errors being encountered whilst playing with the mappings: 使用映射时遇到的常见错误:

1) The UPDATE statement conflicted with the FOREIGN KEY constraint 1)UPDATE语句与FOREIGN KEY约束冲突

2) {"broken column mapping for: Destination.id of: GilesSabreConnection.Profiling.Model.BookingEngineModel.Model.GTIFlightSegment, type component[Code,IsCity] expects 2 columns, but 1 were mapped"} 2){“以下对象的断开的列映射:GilesSabreConnection.Profiling.Model.BookingEngineModel.Model.GTIFlightSegment的Destination.id,类型component [Code,IsCity]期望2列,但映射了1列”}

3) {"Foreign key (FK582A9C81E6C3913B:GTIFlightSegment [Destination_id])) must have same number of columns as the referenced primary key (GTIDestinationAirport [CODE, isCity])"} 3){“外键(FK582A9C81E6C3913B:GTIFlightSegment [Destination_id]))的列数必须与引用的主键(GTIDestinationAirport [CODE,isCity])相同”}}

In case it's needed the fluent config is: 万一需要流利的配置是:

return Fluently.Configure().Database(MsSqlConfiguration.MsSql2012.ConnectionString(@"Data Source=Dev2;Initial Catalog=Sandbox;Integrated Security=True")).Mappings(m => m.FluentMappings.AddFromAssemblyOf<Profile>()).ExposeConfiguration(cfg => new SchemaUpdate(cfg).Execute(true, true)).BuildSessionFactory();

Any help to point me in the right direction from the database and fluent gurus would be greatly appreciated. 从数据库和流利的专家那里为我指明正确方向的任何帮助将不胜感激。

Many thanks in advance. 提前谢谢了。

Realised that by setting the GTIAirport Map as readonly I was inherently making the Destination and Origin maps as readonly so the mapping could never work no matter how I was configuring the relationships. 意识到通过将GTIAirport映射设置为只读,我固有地将“目的地”和“原始”映射设置为只读,因此无论我如何配置关系,该映射都永远无法工作。

So I've split the static reference database of detailed airport info accessed via the View named GTIAiport into two, so the Boolean in the composite key is no longer required. 因此,我已将通过名为GTIAiport的视图访问的详细机场信息的静态参考数据库分为两部分,因此不再需要复合键中的布尔值。 I now have the flight segment mapping simply logging the Airport origin/destination codes within the flight segment table using the Component class in fluent. 现在,我可以使用fluent的Component类,将航段映射简单地记录在航段表中的机场始发/目的地代码。 In the Airport class itself now have a function to independently fetch the rich data from the static reference database table on request using the stored Airport code. 现在,在Airport类中,它本身具有一项功能,可以根据要求使用存储的Airport代码从静态参考数据库表中独立获取丰富数据。

Couldn't figure out a way to do this with fluent. 无法找到一种方法来流畅地做到这一点。 Interested to know if there is a way. 有兴趣知道是否有办法。

public GTIFlightSegmentMap()
        {
            Id(x => x.ID);

            Component(x => x.Destination, m =>
            {
                m.Map(y => y.Code).Column("DestinationCode");

            });
            Component(x => x.Origin, m =>
            {
                m.Map(y => y.Code).Column("OriginCode");

            });
           ;       
            References(x => x.Parent).Not.Nullable();


        }
    }

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

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