Well, I will offer a new answer (a little late, sorry) that will work even if the association name changes.
This method will look for the association property of the main object, and then it will look for the value in the main table. Imagine that:
Table: Orders with the Customers table on Orders.CustomerID is equal to Customers.Id . Therefore, we pass the meta-information of the main table, the CustomerID field (which is the reference field) and the Name field (which we want).
/// <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 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; }
And the call:
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" , "Name" );
The problem is that it only works with foreign keys with only one reference field. But switching to a few keys is pretty trivial.
This is a method to get the field value of the main table, which you can change to return the entire object.
PS I think that I am mistaken in my English, it is quite difficult for me.
Dani rodríguez
source share