代码之家  ›  专栏  ›  技术社区  ›  Ocelot20

SQLMetal多个外键指向一个表问题

  •  6
  • Ocelot20  · 技术社区  · 15 年前

    -清理问题以更好地反映实际问题:

    • record.FK\u帮助
    • 记录.FK\u出价
    • 录制.FKA
    • 录制.FKB

    …这正是我所期望的。问题是,SQLMetal生成的类产生以下属性:

    • record.FK\u帮助
    • 录制.FKA

    能够 只需保存生成的类,这样fkbtablenamegoesher就可以成为FK\u B,但是生成的文件经常被不同的团队成员更改,这将是一个巨大的痛苦。有什么简单的解决办法吗?

    提前谢谢。

    编辑2 所以,我认为解决方案是创建一个具有我想要的属性的分部类,并让getter/setter指向名称不正确的属性。这对选择有用,但不适用于where子句等。有人有办法吗??

    4 回复  |  直到 15 年前
        1
  •  4
  •   Community Mohan Dere    8 年前

    因此,我的解决方案是只添加另一个分部类,并添加一个get/set指向奇怪命名的fkbtablenamegoesher属性的属性。这样我们就不必一直修改生成的类。不能完全解决问题,但应该让开发商更清楚房产意味着什么。有人看到这个解决方案有什么潜在的问题吗?

    -所以,显然这只适用于选择数据,而不是基于数据进行过滤。不像我希望的那么容易修复。有人有其他建议吗?

    -天哪,我以为这是个常见的问题,但我想不是。不管怎样,事实证明我的想法是对的。我发现这个帖子:

    Multiple foreign keys to the same table

    这让我想到,我不能直接链接到另一个属性的getter/setter,因为在幕后可能还有很多事情要做。这家伙的解决方案不完全是答案,但它送我向正确的方向。添加关联属性是它的最终目的:

    public partial class ProblemClass
    {
        [Association(Name = "FK__SomeLinkHere", Storage = "_OriginalPoorlyNamedStorageVariable", ThisKey = "FK_1_Id", OtherKey = "Id", IsForeignKey = true)]
        public FKType MyNewBetterName
        {
            get
            {
                return this._OriginalPoorlyNamedStorageVariable.Entity;
            }
    
            set
            {
                this.OriginalPoorlyNamedStorageVariable = value;
            }
        }
    }
    

        2
  •  0
  •   Dani Rodríguez    13 年前

    好的,我会提出一个新的答案(有点晚了,对不起),即使协会的名称发生了变化,这个答案仍然有效。

    表格: Orders Customers 通过 Orders.CustomerID 等于 Customers.Id CustomerID (这是引用的字段)和 Name (这是我们想要的价值)。

    /// <summary>
    /// Gets the value of "referencedValueFieldName" of an associated table of the "fieldName" in the "mainTable".
    /// This is equivalent of doing the next LINQ query:
    ///   var qryForeignValue = 
    ///     from mt in modelContext.mainTable
    ///     join at in modelContext.associatedTable
    ///       on mt.fieldName equals at.associatedField
    ///     select new { Value = at.referencedValueField }
    /// </summary>
    /// <param name="mainTable">Metadata of the table of the fieldName's field</param>
    /// <param name="fieldName">Name of the field of the foreign key</param>
    /// <param name="referencedValueFieldName">Which field of the foreign table do you the value want</param>
    /// <returns>The value of the referenced table</returns>
    /// <remarks>This method only works with foreign keys of one field.</remarks>
    private Object GetForeignValue(MetaTable mainTable, string fieldName, string referencedValueFieldName) {
      Object resultValue = null;
      foreach (MetaDataMember member in mainTable.RowType.DataMembers) {
        if ((member.IsAssociation) && (member.Association.IsForeignKey)) {
          if (member.Association.ThisKey[0].Name == fieldName) {
            Type associationType = fPointOfSaleData.GetType();
            PropertyInfo associationInfo = associationType.GetProperty(member.Name);
            if (associationInfo == null)
              throw new Exception("Association property not found on member");
    
            Object associationValue = associationType.InvokeMember(associationInfo.Name, BindingFlags.GetProperty, null, fPointOfSaleData, null);
    
            if (associationValue != null) {
              Type foreignType = associationValue.GetType();
              PropertyInfo foreignInfo = foreignType.GetProperty(referencedValueFieldName);
              if (foreignInfo == null)
                throw new Exception("Foreign property not found on assiciation member");
    
              resultValue = foreignType.InvokeMember(foreignInfo.Name, BindingFlags.GetProperty, null, associationValue, null);
            }
    
            break;
          }
        }
      }
      return resultValue;
    }
    

          AttributeMappingSource mapping = new System.Data.Linq.Mapping.AttributeMappingSource();
          MetaModel model = mapping.GetModel(typeof(WhateverClassesDataContext));
          MetaTable table = model.GetTable(typeof(Order));
          Object value = GetForeignValue(table, "CustomerId" /* In the main table */, "Name" /* In the master table */);
    

    这是一个获取主表某个字段值的方法,可以修改为返回整个对象。

        3
  •  0
  •   D. Patrick    13 年前

    这个问题很久以前就有了,但我只是碰到了这个问题。我使用的是DBML,我通过编辑关系解决了这个问题。如果展开ParentProperty,则可以通过更改name属性来设置属性名称。

    以下是来自DBML的XML(成员属性已更改):

      <Association Name="State_StateAction1" Member="DestinationState" ThisKey="DestinationStateId" OtherKey="Id" Type="State" IsForeignKey="true" />
    
        4
  •  0
  •   Community Mohan Dere    8 年前

    public partial class ProblemClass
    {
        partial void OnCreated()
        {
            this._MyNewBetterName = default(EntityRef<FKType>);
        }
        protected EntityRef<FKType> _MyNewBetterName;
    
        [Association(Name = "FK__SomeLinkHere", Storage = "_MyNewBetterName", ThisKey = "FK_1_Id", OtherKey = "Id", IsForeignKey = true)]
        public EntityRef<FKType> MyNewBetterName
        {
            get
            {
                return this._MyNewBetterName.Entity;
            }
    
            set
            {
                this.MyNewBetterName = value;
            }
        }
    }
    

    OnCreated() 在每个部分中,因为这些部分不能在c#中继承( see this ).

    推荐文章