/// <summary> /// <para> /// Gets a property on the given entity type. Returns <see langword="null" /> if no property is found. /// </para> /// <para> /// This API only finds scalar properties and does not find navigation properties. Use /// <see cref="FindNavigation(IMutableEntityType, MemberInfo)" /> to find a navigation property. /// </para> /// </summary> /// <param name="entityType"> The entity type. </param> /// <param name="propertyInfo"> The property on the entity class. </param> /// <returns> The property, or <see langword="null" /> if none is found. </returns> public static IMutableProperty FindProperty([NotNull] this IMutableEntityType entityType, [NotNull] PropertyInfo propertyInfo) { Check.NotNull(entityType, nameof(entityType)); Check.NotNull(propertyInfo, nameof(propertyInfo)); return(propertyInfo.IsIndexerProperty() ? null : entityType.FindProperty(propertyInfo.GetSimpleMemberName())); }
private static void CloneIndexes(IReadOnlyEntityType sourceEntityType, IMutableEntityType targetEntityType) { foreach (var index in sourceEntityType.GetDeclaredIndexes()) { var clonedIndex = targetEntityType.AddIndex( index.Properties.Select(p => targetEntityType.FindProperty(p.Name)).ToList()); clonedIndex.IsUnique = index.IsUnique; index.GetAnnotations().ForEach(annotation => clonedIndex[annotation.Name] = annotation.Value); } }
public static void AddSoftDeleteQueryFilter(this IMutableEntityType entityData) { var methodToCall = typeof(SoftDeleteQueryExtension).GetMethod(nameof(GetSoftDeleteFilter), BindingFlags.NonPublic | BindingFlags.Static) .MakeGenericMethod(entityData.ClrType); var filter = methodToCall.Invoke(null, new object[] { }); entityData.SetQueryFilter((LambdaExpression)filter); entityData.AddIndex(entityData.FindProperty(nameof(ISoftDelete.SoftDeleted))); }
/// <summary> /// 构建租户Id以及假删除过滤器 /// </summary> /// <param name="entityBuilder"></param> /// <param name="dbContext"></param> /// <param name="isDeletedKey"></param> /// <param name="filterValue"></param> /// <returns></returns> protected static LambdaExpression TenantIdAndFakeDeleteQueryFilterExpression(EntityTypeBuilder entityBuilder, DbContext dbContext, string onTableTenantId = null, string isDeletedKey = null, object filterValue = null) { onTableTenantId ??= "TenantId"; isDeletedKey ??= "IsDeleted"; IMutableEntityType metadata = entityBuilder.Metadata; if (metadata.FindProperty(onTableTenantId) == null || metadata.FindProperty(isDeletedKey) == null) { return(null); } Expression finialExpression = Expression.Constant(true); ParameterExpression parameterExpression = Expression.Parameter(metadata.ClrType, "u"); // 租户过滤器 if (entityBuilder.Metadata.ClrType.BaseType.Name == typeof(DEntityTenant).Name) { if (metadata.FindProperty(onTableTenantId) != null) { ConstantExpression constantExpression = Expression.Constant(onTableTenantId); MethodCallExpression right = Expression.Call(Expression.Constant(dbContext), dbContext.GetType().GetMethod("GetTenantId")); finialExpression = Expression.AndAlso(finialExpression, Expression.Equal(Expression.Call(typeof(EF), "Property", new Type[1] { typeof(object) }, parameterExpression, constantExpression), right)); } } // 假删除过滤器 if (metadata.FindProperty(isDeletedKey) != null) { ConstantExpression constantExpression = Expression.Constant(isDeletedKey); ConstantExpression right = Expression.Constant(filterValue ?? false); var fakeDeleteQueryExpression = Expression.Equal(Expression.Call(typeof(EF), "Property", new Type[1] { typeof(bool) }, parameterExpression, constantExpression), right); finialExpression = Expression.AndAlso(finialExpression, fakeDeleteQueryExpression); } return(Expression.Lambda(finialExpression, parameterExpression)); }
private void AddSoftDeleteQueryFilter(IMutableEntityType entityData) { var methodToCall = GetType() .GetMethod(nameof(GetSoftDeleteFilter), BindingFlags.NonPublic | BindingFlags.Instance) .MakeGenericMethod(entityData.ClrType); var filter = methodToCall.Invoke(this, new object[] { }); entityData.SetQueryFilter((LambdaExpression)filter); entityData.AddIndex(entityData.FindProperty(nameof(ISingleSoftDelete.SoftDeleted))); }
private void DoKeyList(List <string> keys, IMutableEntityType et, KeyAction action) { if (keys == default || keys.Count == 0) { return; } List <IMutableProperty> properties = new(); keys.Do(k => properties.Add(et.FindProperty(k))); action(et, properties); }
public static void SetSingleQueryFilter(this IMutableEntityType entityData, SingleQueryFilterTypes queryFilterType, IUserId userIdProvider = null) { var methodName = $"Get{queryFilterType}Filter"; var methodToCall = typeof(SingleQueryFilterExtensions) .GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Static) .MakeGenericMethod(entityData.ClrType); var filter = methodToCall .Invoke(null, new object[] { userIdProvider }); entityData.SetQueryFilter((LambdaExpression)filter); if (queryFilterType == SingleQueryFilterTypes.SingleSoftDelete || queryFilterType == SingleQueryFilterTypes.SingleSoftDeleteDdd) { entityData.AddIndex(entityData.FindProperty(nameof(ISingleSoftDelete.SoftDeleted))); } if (queryFilterType == SingleQueryFilterTypes.SingleSoftDeleteAndUserId) { entityData.AddIndex(entityData.FindProperty(nameof(IUserId.UserId))); } }
public static void AddSoftDeleteQueryFilter( //#C this IMutableEntityType entityData, //#D MyQueryFilterTypes queryFilterType, //#E IUserId userIdProvider = null) //#F { var methodName = $"Get{queryFilterType}Filter"; //#G var methodToCall = typeof(SoftDeleteQueryExtensions) //#G .GetMethod(methodName, //#G BindingFlags.NonPublic | BindingFlags.Static) //#G .MakeGenericMethod(entityData.ClrType); //#G var filter = methodToCall //#G .Invoke(null, new object[] { userIdProvider }); //#G entityData.SetQueryFilter((LambdaExpression)filter); //#H if (queryFilterType == MyQueryFilterTypes.SoftDelete) { entityData.AddIndex(entityData.FindProperty(nameof(ISoftDelete.SoftDeleted))); } if (queryFilterType == MyQueryFilterTypes.UserId) { entityData.AddIndex(entityData.FindProperty(nameof(IUserId.UserId))); } }
private static void CloneKeys(IReadOnlyEntityType sourceEntityType, IMutableEntityType targetEntityType) { foreach (var key in sourceEntityType.GetDeclaredKeys()) { var clonedKey = targetEntityType.AddKey( key.Properties.Select(p => targetEntityType.FindProperty(p.Name)).ToList()); if (key.IsPrimaryKey()) { targetEntityType.SetPrimaryKey(clonedKey.Properties); } key.GetAnnotations().ForEach(annotation => clonedKey[annotation.Name] = annotation.Value); } }
private static void CloneForeignKeys(IReadOnlyEntityType sourceEntityType, IMutableEntityType targetEntityType) { foreach (var foreignKey in sourceEntityType.GetDeclaredForeignKeys()) { var targetPrincipalEntityType = targetEntityType.Model.FindEntityType(foreignKey.PrincipalEntityType.Name); var clonedForeignKey = targetEntityType.AddForeignKey( foreignKey.Properties.Select(p => targetEntityType.FindProperty(p.Name)).ToList(), targetPrincipalEntityType.FindKey( foreignKey.PrincipalKey.Properties.Select(p => targetPrincipalEntityType.FindProperty(p.Name)).ToList()), targetPrincipalEntityType); clonedForeignKey.IsUnique = foreignKey.IsUnique; clonedForeignKey.IsRequired = foreignKey.IsRequired; foreignKey.GetAnnotations().ForEach(annotation => clonedForeignKey[annotation.Name] = annotation.Value); } }
/// <summary> /// Gets the property with the given name, or creates a new one if one is not already defined. /// </summary> /// <param name="entityType"> The entity type to get or add the property to. </param> /// <param name="name"> The name of the property. </param> /// <param name="propertyType"> The type of value the property will hold. </param> /// <returns> The existing or newly created property. </returns> public static IMutableProperty GetOrAddProperty( [NotNull] this IMutableEntityType entityType, [NotNull] string name, [NotNull] Type propertyType) { Check.NotNull(entityType, nameof(entityType)); Check.NotNull(propertyType, nameof(propertyType)); var property = entityType.FindProperty(name); if (property != null) { property.ClrType = propertyType; return(property); } return(entityType.AddProperty(name, propertyType)); }
/// <summary> /// Gets the property with the given name, or creates a new one if one is not already defined. /// </summary> /// <param name="entityType"> The entity type to get or add the property to. </param> /// <param name="propertyInfo"> The corresponding property in the entity class. </param> /// <returns> The existing or newly created property. </returns> public static IMutableProperty GetOrAddProperty( [NotNull] this IMutableEntityType entityType, [NotNull] PropertyInfo propertyInfo) { Check.NotNull(entityType, nameof(entityType)); Check.NotNull(propertyInfo, nameof(propertyInfo)); var property = entityType.FindProperty(propertyInfo); if (property != null) { property.ClrType = propertyInfo.PropertyType; property.IsShadowProperty = false; return(property); } return(entityType.AddProperty(propertyInfo)); }
protected IMutableKey CreateKey(IMutableEntityType entityType, int startingPropertyIndex = -1, int propertyCount = 1) { if (startingPropertyIndex == -1) { startingPropertyIndex = entityType.PropertyCount() - 1; } var keyProperties = new IMutableProperty[propertyCount]; for (var i = 0; i < propertyCount; i++) { var propertyName = "P" + (startingPropertyIndex + i); keyProperties[i] = entityType.FindProperty(propertyName) ?? entityType.AddProperty(propertyName, typeof(int?)); keyProperties[i].IsNullable = false; } return(entityType.AddKey(keyProperties)); }
private static void AddSmartEnumAndKeyedValueObjects( bool validateOnWrite, Dictionary <Type, ValueConverter> converterLookup, Action <IMutableProperty> configure, IMutableEntityType entity) { foreach (var propertyInfo in entity.ClrType.GetRuntimeProperties()) { // will be handled by "AddConvertersForNavigations" if (entity.FindNavigation(propertyInfo) is not null) { continue; } // wil be handled by AddConverterForScalarProperties if (entity.FindProperty(propertyInfo) is not null) { continue; } if (!propertyInfo.IsCandidateProperty()) { continue; } var propertyType = propertyInfo.PropertyType; var metadata = ValueObjectMetadataLookup.Find(propertyType); if (metadata is null) { continue; } var property = entity.AddProperty(propertyInfo); SetConverterAndExecuteCallback(validateOnWrite, converterLookup, configure, property); } }
private static void AddNonKeyedValueObjectMembers(IMutableEntityType entity) { if (entity.ClrType.GetCustomAttribute <KeyedValueObjectAttribute>() is not null) { return; } var ctorAttr = entity.ClrType.GetCustomAttribute <ValueObjectConstructorAttribute>(); if (ctorAttr is null || ctorAttr.Members.Length == 0) { return; } foreach (var memberName in ctorAttr.Members) { var property = entity.FindProperty(memberName); if (property is null) { entity.AddProperty(memberName); } } }
/// <summary> /// Gets the property with the given name, or creates a new one if one is not already defined. /// </summary> /// <param name="entityType"> The entity type to get or add the property to. </param> /// <param name="propertyInfo"> The corresponding property in the entity class. </param> /// <returns> The existing or newly created property. </returns> /// <remarks> The returned property might not have the specified type and shadowness. </remarks> public static IMutableProperty GetOrAddProperty([NotNull] this IMutableEntityType entityType, [NotNull] PropertyInfo propertyInfo) => entityType.FindProperty(propertyInfo) ?? entityType.AddProperty(propertyInfo);
/// <summary> /// Gets the property with the given name, or creates a new one if one is not already defined. /// </summary> /// <param name="entityType"> The entity type to get or add the property to. </param> /// <param name="name"> The name of the property. </param> /// <param name="propertyType"> The type of value the property will hold. </param> /// <returns> The existing or newly created property. </returns> /// <remarks> The returned property might not have the specified type and shadowness. </remarks> public static IMutableProperty GetOrAddProperty( [NotNull] this IMutableEntityType entityType, [NotNull] string name, [CanBeNull] Type propertyType) => entityType.FindProperty(name) ?? entityType.AddProperty(name, propertyType);