Из того, что я вижу в шаблоне T4 по умолчанию, свойства внешнего ключа сущностей не связаны напрямую со ссылкой на сущность, связанную с ключом.
Есть пары, подходящие к вашей проблеме в отношении миграции изLinq для SQL в EF4.Одним из них будет регистрация на событие AssociationChanged
ваших ассоциаций, чтобы оно автоматически обновляло ваше поле.В вашем контексте один из подходов может выглядеть примерно так:
// Extends Employee entity
public partial class Employee
{
private void CompanyChanged(Object sender, CollectionChangeEventArgs e)
{
// Apply reactive changes; aka set CompanyID
// here
}
// Create a default constructor that registers your event handler
public Employee()
{
this.CompanyReference.AssociationChanged += CompanyChanged;
}
}
Лично, если вы хотите ограничить обслуживание, необходимое для поддержки такой логики, я бы предложил изменить ваш шаблон T4 (либо изменитьэто самостоятельно или найдите), чтобы установить CompanyId
при изменении Company
, как показано ранее.
Гил Финк написал довольно хорошее введение в шаблоны T4 с EF4, и вы можете посмотреть Скотт Хансельман , обернул множество полезных ссылок и ресурсов для работы сШаблоны T4.
На последнем замечании, если я не ошибаюсь, прямой доступ к внешним ключам в качестве свойств объекта является чем-то новым от EF3.5 до 4. В 3.5 единственный доступ к нему был только черезсвязанный объект (Employee.Company.CompanyID
).Я полагаю, что эта функция была добавлена в EF4, чтобы вам не приходилось загружать ассоциации (используя «include»), чтобы получить внешний ключ при выборе из хранилища данных.
Возможно, EF примет этобыть, если у вас есть ассоциация, сначала пройдите через ассоциацию, чтобы получить удостоверение личности.Но это всего лишь предположение, поскольку я не получил никаких цитат, подтверждающих это.
[EDIT 2010-06-16] : После быстрого изучения и анализа xml-элементов edmx я нашел одинназывается ReferentialConstraint, который, по-видимому, содержит поля внешнего ключа для конкретного FK_Relation.
Здесь фрагмент кода для изменения в шаблоне edmx T4 по умолчанию, раздел Запись свойств навигации.(Template_RegionNavigationProperties
), около строки 388 неизмененного шаблона.Попробуйте игнорировать ужасное форматирование ...
<#=code.SpaceAfter(NewModifier(navProperty))#><#=Accessibility.ForProperty(navProperty)#> <#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#> <#=code.Escape(navProperty)#>
{
<#=code.SpaceAfter(Accessibility.ForGetter(navProperty))#>get
{
return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#>>("<#=navProperty.RelationshipType.FullName#>", "<#=navProperty.ToEndMember.Name#>").Value;
}
<#=code.SpaceAfter(Accessibility.ForSetter(navProperty))#>set
{
// edit begins here
if(value != null)
{
// Automatically sets the foreign key attributes according to linked entity
<#
AssociationType association = GetSourceSchemaTypes<AssociationType>().FirstOrDefault(_ => _.FullName == navProperty.RelationshipType.FullName);
foreach(var cons in association.ReferentialConstraints)
{
foreach(var metadataProperty in cons.FromProperties)
{
#>
this.<#=metadataProperty.Name#> = value.<#=metadataProperty.Name#>;
//this._<#=metadataProperty.Name#> = value._<#=metadataProperty.Name#>; // use private field to bypass the OnChanged events, property validation and the likes..
<#
}
}
#>
}
else
{
// what usually happens in Linq-to-SQL when an association is set to null
// here
}
// edit ends here
((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<<#=MultiSchemaEscape(navProperty.ToEndMember.GetEntityType(), code)#>>("<#=navProperty.RelationshipType.FullName#>", "<#=navProperty.ToEndMember.Name#>").Value = value;
}
}
Я грубо проверил его, но это факт, что есть некоторая проверка и такая пропущенная.Возможно, это может дать вам подсказку к решению независимо.