Каковы изменения EF Core 2.1 в собственных типах?
Docs последний раз менялся 26.02.2018, но есть некоторые критические изменения, которые мне нужно исправить.
У меня есть Тип MyProcessContext
, используемый как принадлежащий для многих сущностей:
public class RequestData
{
public Guid CorrelationId { get; set; }
public DateTime Updated { get; set; }
public MyProcessContext ProcessContext { get; set; }
}
public class MyProcessContext
{
public int ClientId { get; set; }
}
public class EntityConfiguration : IEntityTypeConfiguration<RequestData>
{
public void Configure(EntityTypeBuilder<RequestData> builder)
{
// all mapped by convention
builder.OwnsOne(x => x.ProcessContext);
builder.Property(x => x.Updated).IsRowVersion();
builder.HasKey(x => x.CorrelationId);
builder.Property(x => x.CorrelationId).ValueGeneratedNever();
}
}
Он работает, как и ожидалось, с EF Core 2.0. В представлении отладки у меня есть разные типы сущностей для каждого использования собственного типа (RequestData.ProcessContext#MyProcessContext
):
EntityType: RequestData
Properties:
CorrelationId (Guid) Required PK AfterSave:Throw 0 0 0 -1 -1
Annotations:
Relational:ColumnName: correlation_id
Updated (DateTime) Required Concurrency BeforeSave:Ignore AfterSave:Ignore ValueGenerated.OnAddOrUpdate 11 11 -1 -1 0
Annotations:
Relational:ColumnName: updated
Navigations:
ProcessContext (<ProcessContext>k__BackingField, MyProcessContext) ToDependent RequestData.ProcessContext#MyProcessContext 0 -1 1 -1 -1
Keys:
CorrelationId PK
Annotations:
Relational:TableName: process_request
RelationshipDiscoveryConvention:NavigationCandidates: System.Collections.Immutable.ImmutableSortedDictionary`2[System.Reflection.PropertyInfo,System.Type]
EntityType: RequestData.ProcessContext#MyProcessContext
Properties:
RequestDataCorrelationId (no field, Nullable<Guid>) Shadow Required PK FK AfterSave:Throw 0 0 0 0 -1
ClientId (int) Required 1 1 -1 -1 -1
Keys:
RequestDataCorrelationId PK
Foreign keys:
RequestData.ProcessContext#MyProcessContext {'RequestDataCorrelationId'} -> RequestData {'CorrelationId'} Unique ToDependent: ProcessContext
Annotations:
Relational:TableName: process_request
RelationshipDiscoveryConvention:NavigationCandidates: System.Collections.Immutable.ImmutableSortedDictionary`2[System.Reflection.PropertyInfo,System.Type]
После обновления отладочное представление содержит
EntityType: RequestData
...
ProcessContext (<ProcessContext>k__BackingField, MyProcessContext) ToDependent MyProcessContext 0 -1 1 -1 -1
...
EntityType: MyProcessContext
Properties:
RequestDataCorrelationId (no field, Guid) Shadow Required PK FK AfterSave:Throw 0 0 0 0 -1
ClientId (int) Required 1 1 -1 -1 -1
Keys:
RequestDataCorrelationId PK
Foreign keys:
MyProcessContext {'RequestDataCorrelationId'} -> RequestData {'CorrelationId'} Unique Ownership ToDependent: ProcessContext
Annotations:
Relational:TableName: process_request
RelationshipDiscoveryConvention:NavigationCandidates: System.Collections.Immutable.ImmutableSortedDictionary`2[System.Reflection.PropertyInfo,System.Type]
Модель, построенная как MyProcessContext
, является обычной сущностью. В коде типа
foreach (var entity in modelBuilder.Model.GetEntityTypes())
{
var entityIsOwned = entity.IsOwned();
entityIsOwned
верно, но entity.DefiningNavigationName
Теперь равно нулю.
Мне нужно это имя дляпользовательского соглашения имен .
1 ответ:
Единственным официальным изменением на данный момент (ядро EF 2.1) является добавление атрибута [Owned] .
Однако, по-видимому, есть прорывные изменения в реализации, поэтому свойства
DefiningEntityType
иDefiningNavigationName
не являются более надежными (они все равно не документируются - просто "стандартный" сгенерированный бесполезный "получает определяющий тип сущности." и "получает имя определяющей навигации.").Экспериментально я обнаружил, что они заселяются только в том случае, если владелец тип используется в нескольких сущностях. Не знаю, почему они это делают, но главное, что мы не должны их использовать, более того, сам код ядра EF, похоже, больше не использует их.
Из того, что я видел,
IsOwned
,DefiningEntityType
а членыDefiningNavigationName
определяются внешним ключом, имеющим свойствоIsOwnership
, равноеtrue
.Другими словами:
var ownershipFk = entityType.GetForeignKeys().FirstOrDefault(fk => fk.IsOwnership); var isOwned = ownershipFk != null; var definingEntityType = ownershipFk?.PrincipalEntityType; var definingNavigationName = ownershipFk?.PrincipalToDependent.Name;