Сценарии - 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 } );