public static Dictionary <string, string> ToDisplayDictionary <TEntity>(this IEntity <TEntity> @this, Expression <Func <TEntity, object> > includes_MemberOrNewExpression) where TEntity : class, IEntity <TEntity>, new() { var propNames = ExpressionEx.GetPropertyNames(includes_MemberOrNewExpression); return(ToDisplayDictionary(@this as IEntity, propNames)); }
/// <summary> /// Accept all property values which are can be read and write from another model, /// but exclude the specified properties. /// (Only ValueTypes, exclude 'KeyAttribute' and attributes which are start with 'Track') /// </summary> /// <typeparam name="TEntity">Instance of IEntity</typeparam> /// <param name="this">Source model</param> /// <param name="model">The model which provide values</param> /// <param name="excludes_MemberOrNewExp">Specifies properties that aren't applied to the source model. /// <para>A lambda expression representing the property(s) (x => x.Url).</para> /// <para> /// If the value is made up of multiple properties then specify an anonymous /// type including the properties (x => new { x.Title, x.BlogId }). /// </para> /// </param> /// <returns></returns> public static TEntity AcceptBut <TEntity>(this TEntity @this, TEntity model, Expression <Func <TEntity, object> > excludes_MemberOrNewExp) where TEntity : class, IEntity { var propNames = ExpressionEx.GetPropertyNames(excludes_MemberOrNewExp); // Filter var type = typeof(TEntity); var props = type.GetProperties() .Where(x => x.CanRead && x.CanWrite) .Where(x => !x.GetCustomAttributes(false).For(attrs => { return(attrs.Any(attr => attr is NotAcceptableAttribute) || attrs.Any(attr => new[] { nameof(KeyAttribute), nameof(AutoCreationTimeAttribute), nameof(AutoLastWriteTimeAttribute) }.Contains(attr.GetType().Name))); })) .Where(x => x.PropertyType.IsBasicType() || x.PropertyType.IsValueType); props = props.Where(x => !propNames.Contains(x.Name)); // Copy values foreach (var prop in props) { prop.SetValue(@this, prop.GetValue(model), null); } return(@this); }
/// <summary> /// /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="this"></param> /// <param name="keys">[Member or NewSelector]</param> /// <param name="entities"></param> /// <param name="initOptions"></param> public static void AddOrUpdateRange <TEntity>(this DbSet <TEntity> @this, Expression <Func <TEntity, object> > keys, IEnumerable <TEntity> entities, Action <UpdateOptions <TEntity> > initOptions) where TEntity : class { if (!entities.Any()) { return; } var options = new UpdateOptions <TEntity>(); initOptions?.Invoke(options); var propNames = ExpressionEx.GetPropertyNames(keys); var parts = entities.Select(x => new { Entity = x, Predicate = GetAddOrUpdateLambda(propNames, x), }); Expression <Func <TEntity, bool> > predicate; if (options.Predicate is null) { var lambdas = parts.Select(x => x.Predicate).ToArray(); predicate = lambdas.LambdaJoin(Expression.OrElse); } else { predicate = options.Predicate; } var records = @this.Where(predicate).ToArray(); foreach (var part in parts) { var partPredicate = part.Predicate.Compile(); var entity = part.Entity; var record = records.FirstOrDefault(partPredicate); if (record is not null) { options.Update(record, entity); @this.GetDbContext().Entry(record); } else { @this.Add(entity); } } }
public static EntityEntry<TEntity> AddOrUpdate<TEntity>(this DbSet<TEntity> @this, Expression<Func<TEntity, object>> memberOrNewSelector, TEntity entity, Action<UpdateOptions<TEntity>> initOptions) where TEntity : class { var options = new UpdateOptions<TEntity>(); initOptions?.Invoke(options); var propNames = ExpressionEx.GetPropertyNames(memberOrNewSelector); var predicate = GetAddOrUpdateLambda(propNames, entity); var record = @this.FirstOrDefault(predicate); if (record is not null) { options.Update(record, entity); return @this.GetDbContext().Entry(record); } else return @this.Add(entity); }