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

Редактировал(а) Alexandr Fokin 2025/06/22 16:10

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