Хорошо, я предложу новый ответ (немного поздно, извините), который будет работать, даже если имя ассоциации изменится.
Этот метод будет искать свойство ассоциации основного объекта, а затем будет искать значение в главной таблице. Представьте себе, что:
Таблица: 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 */);
Проблема в том, что работает только с внешними ключами только с одним указанным полем. Но переключение на несколько клавиш довольно тривиально.
Это метод для получения значения поля основной таблицы, который можно изменить, чтобы он возвращал весь объект.
PS: Я думаю, что делаю некоторые ошибки в своем английском, это довольно сложно для меня.