Исходный код вики linq2db. InsertOrUpdate all properties.

Версия 1.2 от Alexandr Fokin на 2025/06/22 16:08

Последние авторы
1 |(% style="width:132px" %) |(% style="width:1304px" %)Framework API содержит insert метод, который позволяет указать entity, не указываю проекцию всех заполняемых свойств.
2 Но у метода InsertOrUpdate я такой вариации не нашел. Ее можно реализовать, собрав выражение [[Expression tree ~~| Деревья выражений>>doc:Разработка.NET.C#.Рантайм и типы.Expression tree | Деревья выражений.WebHome]] руками.
3 |(% style="width:132px" %) |(% style="width:1304px" %)(((
4 |(% style="width:212px" %)Вызов с ручным маппингом|(% style="width:1050px" %){{code language="c#"}}await dbContext.Entities.InsertOrUpdateAsync(
5 () => new MyEntity()
6 {
7 UniqueKey = entity.UniqueKey
8 },
9 onDuplicateKeyUpdateSetter: null,
10 keySelector: () => new MyEntity() { UniqueKey = default }
11 );{{/code}}
12 |(% style="width:212px" %)Автоматическое формирование выражение с заполнением всех insert свойств.|(% style="width:1050px" %){{code language="c#"}}public static class LinqToDBHelper
13 {
14 public static Expression<Func<T>> InsertInitAllExpression<T>(
15 T instance,
16 MappingSchema? schema = null)
17 where T : class, new()
18 {
19 var type = typeof(T);
20
21 schema = schema ?? MappingSchema.Default;
22 var descriptor = schema.GetEntityDescriptor(type);
23
24 var toInsert = descriptor.Columns.Where(c => !c.SkipOnInsert);
25 var param = Expression.Parameter(typeof(T));
26
27 var newExpression = Expression.New(type);
28
29 var instanceExpression = Expression.Constant(instance);
30 var memberInitExpression = Expression.MemberInit(
31 newExpression,
32 toInsert.Select(
33 e => Expression.Bind(
34 e.MemberInfo,
35 Expression.MakeMemberAccess(
36 instanceExpression,
37 e.MemberInfo
38 )
39 )
40 )
41 );
42
43 var result = Expression.Lambda<Func<T>>(memberInitExpression);
44 return result;
45 }
46 }{{/code}}
47 |(% style="width:212px" %)Использование автоматического выражения.|(% style="width:1050px" %){{code language="c#"}}await dbContext.Entities.InsertOrUpdateAsync(
48 LinqToDBHelper.InsertInitAllExpression(entity, dbContext.MappingSchema),
49 onDuplicateKeyUpdateSetter: null,
50 keySelector: () => new MyEntity() { UniqueKey = default }
51 );{{/code}}
52
53
54 )))
55 |(% style="width:132px" %) |(% style="width:1304px" %)