Сценарии - linq2db. InsertOrUpdate all properties. 

Page / - Изменено Alexandr Fokin в 2025/06/22 16:08 

linq2db. InsertOrUpdate all properties. 
Изменено Alexandr Fokin
в 2025/06/22 16:08

Оглавление

 	Framework API содержит insert метод, который позволяет указать entity, не указываю проекцию всех заполняемых свойств.
Но у метода InsertOrUpdate я такой вариации не нашел. Ее можно реализовать, собрав выражение Expression tree | Деревья выражений руками.	
 	Expression to create an instance with object initializer in C#
https://www.iditect.com/faq/csharp/expression-to-create-an-instance-with-object-initializer-in-c.html	
 	Вызов с ручным маппингом	await dbContext.Entities.InsertOrUpdateAsync(
 () => new MyEntity() 
 {
  UniqueKey = entity.UniqueKey
 },
 onDuplicateKeyUpdateSetter: null,
 keySelector: () => new MyEntity() { UniqueKey = default }
 );	
Автоматическое формирование выражение с заполнением всех insert свойств.	public static class LinqToDBHelper
{
   public static Expression<Func<T>> InsertInitAllExpression<T>(
        T instance, 
        MappingSchema? schema = null) 
       where T : class, new()
    {
       var type = typeof(T);

        schema = schema ?? MappingSchema.Default;
       var descriptor = schema.GetEntityDescriptor(type);

       var toInsert = descriptor.Columns.Where(c => !c.SkipOnInsert);
       var param = Expression.Parameter(typeof(T));

       var newExpression = Expression.New(type);

       var instanceExpression = Expression.Constant(instance);
       var memberInitExpression = Expression.MemberInit(
            newExpression,
            toInsert.Select(
                e => Expression.Bind(
                    e.MemberInfo,
                    Expression.MakeMemberAccess(
                        instanceExpression,
                        e.MemberInfo
                        )
                    )
                )
            );

       var result = Expression.Lambda<Func<T>>(memberInitExpression);
       return result;
    }
}	
Использование автоматического выражения.	await dbContext.Entities.InsertOrUpdateAsync(
 LinqToDBHelper.InsertInitAllExpression(entity, dbContext.MappingSchema),
 onDuplicateKeyUpdateSetter: null,
 keySelector: () => new MyEntity() { UniqueKey = default  }
 );