diff --git a/generator/.DevConfigs/9490947f-209f-47e9-8c70-3698872df304.json b/generator/.DevConfigs/9490947f-209f-47e9-8c70-3698872df304.json
new file mode 100644
index 000000000000..9d9d47707213
--- /dev/null
+++ b/generator/.DevConfigs/9490947f-209f-47e9-8c70-3698872df304.json
@@ -0,0 +1,11 @@
+{
+ "services": [
+ {
+ "serviceName": "DynamoDBv2",
+ "type": "minor",
+ "changeLogMessages": [
+ "Add support for DynamoDbUpdateBehavior for operations."
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/sdk/src/Services/DynamoDBv2/Custom/DataModel/Attributes.cs b/sdk/src/Services/DynamoDBv2/Custom/DataModel/Attributes.cs
index 64978ed49e03..0ff6ea3fb306 100644
--- a/sdk/src/Services/DynamoDBv2/Custom/DataModel/Attributes.cs
+++ b/sdk/src/Services/DynamoDBv2/Custom/DataModel/Attributes.cs
@@ -733,4 +733,62 @@ public DynamoDBAutoGeneratedTimestampAttribute(string attributeName, [Dynamicall
{
}
}
+
+ ///
+ /// Specifies the update behavior for a property when performing DynamoDB update operations.
+ /// This attribute can be used to control whether a property is always updated, only updated if not null.
+ ///
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
+ public sealed class DynamoDbUpdateBehaviorAttribute : DynamoDBPropertyAttribute
+ {
+ ///
+ /// Gets the update behavior for the property.
+ ///
+ public UpdateBehavior Behavior { get; }
+
+ ///
+ /// Default constructor. Sets behavior to Always.
+ ///
+ public DynamoDbUpdateBehaviorAttribute()
+ : base()
+ {
+ Behavior = UpdateBehavior.Always;
+ }
+
+ ///
+ /// Constructor that specifies the update behavior.
+ ///
+ /// The update behavior to apply.
+ public DynamoDbUpdateBehaviorAttribute(UpdateBehavior behavior)
+ : base()
+ {
+ Behavior = behavior;
+ }
+
+ ///
+ /// Constructor that specifies an alternate attribute name and update behavior.
+ ///
+ /// Name of attribute to be associated with property or field.
+ /// The update behavior to apply.
+ public DynamoDbUpdateBehaviorAttribute(string attributeName, UpdateBehavior behavior)
+ : base(attributeName)
+ {
+ Behavior = behavior;
+ }
+ }
+
+ ///
+ /// Specifies when a property value should be set.
+ ///
+ public enum UpdateBehavior
+ {
+ ///
+ /// Set the value on both create and update.
+ ///
+ Always,
+ ///
+ /// Set the value only when the item is created.
+ ///
+ IfNotExists
+ }
}
diff --git a/sdk/src/Services/DynamoDBv2/Custom/DataModel/Context.cs b/sdk/src/Services/DynamoDBv2/Custom/DataModel/Context.cs
index 114d24d19dae..70637c0f4792 100644
--- a/sdk/src/Services/DynamoDBv2/Custom/DataModel/Context.cs
+++ b/sdk/src/Services/DynamoDBv2/Custom/DataModel/Context.cs
@@ -1,17 +1,17 @@
/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
+* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+*
+* Licensed under the Apache License, Version 2.0 (the "License").
+* You may not use this file except in compliance with the License.
+* A copy of the License is located at
+*
+* http://aws.amazon.com/apache2.0
+*
+* or in the "license" file accompanying this file. This file is distributed
+* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+* express or implied. See the License for the specific language governing
+* permissions and limitations under the License.
+*/
using System;
using System.Collections.Generic;
@@ -375,31 +375,35 @@ public IMultiTableTransactWrite CreateMultiTableTransactWrite(params ITransactWr
Document updateDocument;
Expression versionExpression = null;
-
- var returnValues=counterConditionExpression == null ? ReturnValues.None : ReturnValues.AllNewAttributes;
- if ((flatConfig.SkipVersionCheck.HasValue && flatConfig.SkipVersionCheck.Value) || !storage.Config.HasVersion)
+ var updateIfNotExistsAttributeName = GetUpdateIfNotExistsAttributeNames(storage);
+
+ var returnValues = counterConditionExpression == null && !updateIfNotExistsAttributeName.Any()
+ ? ReturnValues.None
+ : ReturnValues.AllNewAttributes;
+
+ var updateItemOperationConfig = new UpdateItemOperationConfig
{
- updateDocument = table.UpdateHelper(storage.Document, table.MakeKey(storage.Document), new UpdateItemOperationConfig()
- {
- ReturnValues = returnValues
- }, counterConditionExpression);
- }
- else
+ ReturnValues = returnValues
+ };
+
+ if (!(flatConfig.SkipVersionCheck.HasValue && flatConfig.SkipVersionCheck.Value) && storage.Config.HasVersion)
{
- var conversionConfig = new DynamoDBEntry.AttributeConversionConfig(table.Conversion, table.IsEmptyStringValueEnabled);
+ var conversionConfig = new DynamoDBEntry.AttributeConversionConfig(table.Conversion, table.IsEmptyStringValueEnabled);
versionExpression = CreateConditionExpressionForVersion(storage, conversionConfig);
SetNewVersion(storage);
-
- var updateItemOperationConfig = new UpdateItemOperationConfig
- {
- ReturnValues = returnValues,
- ConditionalExpression = versionExpression,
- };
- updateDocument = table.UpdateHelper(storage.Document, table.MakeKey(storage.Document), updateItemOperationConfig, counterConditionExpression);
+ updateItemOperationConfig.ConditionalExpression = versionExpression;
}
- if (counterConditionExpression == null && versionExpression == null) return;
+ updateDocument = table.UpdateHelper(
+ storage.Document,
+ table.MakeKey(storage.Document),
+ updateItemOperationConfig,
+ counterConditionExpression,
+ updateIfNotExistsAttributeName
+ );
+
+ if (counterConditionExpression == null && versionExpression == null && !updateIfNotExistsAttributeName.Any()) return;
if (returnValues == ReturnValues.AllNewAttributes)
{
@@ -428,36 +432,36 @@ private async Task SaveHelperAsync([DynamicallyAccessedMembers(InternalConstants
Document updateDocument;
Expression versionExpression = null;
- var returnValues = counterConditionExpression == null ? ReturnValues.None : ReturnValues.AllNewAttributes;
+ var updateIfNotExistsAttributeName = GetUpdateIfNotExistsAttributeNames(storage);
+
+ var returnValues = counterConditionExpression == null && !updateIfNotExistsAttributeName.Any()
+ ? ReturnValues.None
+ : ReturnValues.AllNewAttributes;
- if (
- (flatConfig.SkipVersionCheck.HasValue && flatConfig.SkipVersionCheck.Value)
- || !storage.Config.HasVersion)
+ var updateItemOperationConfig = new UpdateItemOperationConfig
{
- updateDocument = await table.UpdateHelperAsync(storage.Document, table.MakeKey(storage.Document), new UpdateItemOperationConfig
- {
- ReturnValues = returnValues
- }, counterConditionExpression, cancellationToken).ConfigureAwait(false);
- }
- else
+ ReturnValues = returnValues
+ };
+
+ if (!(flatConfig.SkipVersionCheck.HasValue && flatConfig.SkipVersionCheck.Value) && storage.Config.HasVersion)
{
- var conversionConfig = new DynamoDBEntry.AttributeConversionConfig(table.Conversion, table.IsEmptyStringValueEnabled);
+ var conversionConfig = new DynamoDBEntry.AttributeConversionConfig(table.Conversion, table.IsEmptyStringValueEnabled);
versionExpression = CreateConditionExpressionForVersion(storage, conversionConfig);
SetNewVersion(storage);
-
- updateDocument = await table.UpdateHelperAsync(
- storage.Document,
- table.MakeKey(storage.Document),
- new UpdateItemOperationConfig
- {
- ReturnValues = returnValues,
- ConditionalExpression = versionExpression
- }, counterConditionExpression,
- cancellationToken)
- .ConfigureAwait(false);
+ updateItemOperationConfig.ConditionalExpression = versionExpression;
}
- if (counterConditionExpression == null && versionExpression == null && !storage.Config.HasAutogeneratedProperties) return;
+ updateDocument = await table.UpdateHelperAsync(
+ storage.Document,
+ table.MakeKey(storage.Document),
+ updateItemOperationConfig,
+ counterConditionExpression,
+ cancellationToken,
+ updateIfNotExistsAttributeName
+ ).ConfigureAwait(false);
+
+
+ if (counterConditionExpression == null && versionExpression == null && !updateIfNotExistsAttributeName.Any()) return;
if (returnValues == ReturnValues.AllNewAttributes)
{
@@ -698,4 +702,4 @@ private async Task SaveHelperAsync([DynamicallyAccessedMembers(InternalConstants
#endregion
}
-}
+}
\ No newline at end of file
diff --git a/sdk/src/Services/DynamoDBv2/Custom/DataModel/ContextInternal.cs b/sdk/src/Services/DynamoDBv2/Custom/DataModel/ContextInternal.cs
index 46f3edeab7c6..998885ac07c1 100644
--- a/sdk/src/Services/DynamoDBv2/Custom/DataModel/ContextInternal.cs
+++ b/sdk/src/Services/DynamoDBv2/Custom/DataModel/ContextInternal.cs
@@ -62,6 +62,7 @@ internal static void SetNewVersion(ItemStorage storage)
}
storage.Document[versionAttributeName] = version;
}
+
private static void IncrementVersion(Type memberType, ref Primitive version)
{
if (memberType.IsAssignableFrom(typeof(Byte))) version = version.AsByte() + 1;
@@ -140,7 +141,7 @@ private static PropertyStorage[] GetCounterProperties(ItemStorage storage)
{
var counterProperties = storage.Config.BaseTypeStorageConfig.Properties.
Where(propertyStorage => propertyStorage.IsCounter).ToArray();
- var flatten= storage.Config.BaseTypeStorageConfig.Properties.
+ var flatten = storage.Config.BaseTypeStorageConfig.Properties.
Where(propertyStorage => propertyStorage.FlattenProperties.Any()).ToArray();
while (flatten.Any())
{
@@ -148,8 +149,7 @@ private static PropertyStorage[] GetCounterProperties(ItemStorage storage)
counterProperties = counterProperties.Concat(flattenCounters).ToArray();
flatten = flatten.SelectMany(p => p.FlattenProperties.Where(fp => fp.FlattenProperties.Any())).ToArray();
}
-
-
+
return counterProperties;
}
@@ -175,12 +175,27 @@ private static DocumentModel.Expression CreateUpdateExpressionForCounterProperti
propertyStorage.CounterStartValue - propertyStorage.CounterDelta;
}
updateExpression.ExpressionStatement = $"SET {asserts.Substring(0, asserts.Length - 2)}";
-
return updateExpression;
}
#endregion
+ internal static List GetUpdateIfNotExistsAttributeNames(ItemStorage storage)
+ {
+ var ifNotExistsProperties = storage.Config.BaseTypeStorageConfig.Properties.
+ Where(propertyStorage => propertyStorage.UpdateBehaviorMode == UpdateBehavior.IfNotExists).ToArray();
+ var flatten = storage.Config.BaseTypeStorageConfig.Properties.
+ Where(propertyStorage => propertyStorage.FlattenProperties.Any()).ToArray();
+ while (flatten.Any())
+ {
+ var flattenIfNotExists = flatten.SelectMany(p => p.FlattenProperties.Where(fp => fp.UpdateBehaviorMode == UpdateBehavior.IfNotExists)).ToArray();
+ ifNotExistsProperties = ifNotExistsProperties.Concat(flattenIfNotExists).ToArray();
+ flatten = flatten.SelectMany(p => p.FlattenProperties.Where(fp => fp.FlattenProperties.Any())).ToArray();
+ }
+ return ifNotExistsProperties.Select(p => p.AttributeName).ToList();
+ }
+
+
#region Table methods
// Retrieves the target table for the specified type
@@ -456,7 +471,7 @@ private void PopulateInstance(ItemStorage storage, object instance, DynamoDBFlat
{
foreach (PropertyStorage propertyStorage in storageConfig.AllPropertyStorage)
{
- if(propertyStorage.IsFlattened) continue;
+ if (propertyStorage.IsFlattened) continue;
string attributeName = propertyStorage.AttributeName;
if (propertyStorage.ShouldFlattenChildProperties)
{
@@ -573,7 +588,6 @@ private void PopulateItemStorage(object toStore, ItemStorage storage, DynamoDBFl
if (ShouldSave(dbe, ignoreNullValues))
{
-
if (propertyStorage.ShouldFlattenChildProperties)
{
if (dbe == null) continue;
@@ -683,14 +697,14 @@ private object FromDynamoDBEntry(SimplePropertyStorage propertyStorage, DynamoDB
bool isAotRuntime = InternalSDKUtils.IsRunningNativeAot();
string errorMessage;
-
+
if (isAotRuntime)
{
errorMessage = $"Unable to convert DynamoDB entry [{entry}] of type {entry.GetType().FullName} to property {propertyStorage.PropertyName} of type {targetType.FullName}. " +
- "Since the application is running in Native AOT mode the type could possibly be trimmed. " +
- "This can happen if the type being created is a nested type of a type being used for saving and loading DynamoDB items. " +
- $"This can be worked around by adding the \"[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof({targetType.FullName}))]\" attribute to the constructor of the parent type." +
- " If the parent type can not be modified the attribute can also be used on the method invoking the DynamoDB sdk or some other method that you are sure is not being trimmed.";
+ "Since the application is running in Native AOT mode the type could possibly be trimmed. " +
+ "This can happen if the type being created is a nested type of a type being used for saving and loading DynamoDB items. " +
+ $"This can be worked around by adding the \"[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof({targetType.FullName}))]\" attribute to the constructor of the parent type." +
+ " If the parent type can not be modified the attribute can also be used on the method invoking the DynamoDB sdk or some other method that you are sure is not being trimmed.";
}
else
{
@@ -1514,7 +1528,7 @@ public ContextSearch(Search search, DynamoDBFlatConfig flatConfig)
DynamoDBFlatConfig flatConfig = new DynamoDBFlatConfig(operationConfig, Config);
ItemStorageConfig storageConfig = StorageConfigCache.GetConfig(flatConfig);
-
+
ContextSearch query;
if (operationConfig is { Expression: { Filter: not null } })
{
@@ -1561,7 +1575,7 @@ internal ContextSearch
ContextSearch query;
if (operationConfig is { Expression: { Filter: not null } })
{
- if(conditions!=null && conditions.Any())
+ if (conditions != null && conditions.Any())
{
throw new InvalidOperationException("Query conditions are not supported with filter expression. Use either Query conditions or filter expression, but not both.");
}
@@ -1848,7 +1862,7 @@ private ExpressionNode HandleAttributeTypeMethodCall(MethodCallExpression expr,
{
var memberObj = ContextExpressionsUtils.GetMember(expr.Arguments[0]);
var typeExpr = ContextExpressionsUtils.GetConstant(expr.Arguments[1]);
- if (memberObj!=null && typeExpr!=null)
+ if (memberObj != null && typeExpr != null)
{
SetExpressionNodeAttributes(storageConfig, memberObj, typeExpr, node, flatConfig);
}
@@ -1990,7 +2004,7 @@ private ExpressionNode HandleStartsWithMethodCall(MethodCallExpression expr, Ite
};
if (expr.Object is MemberExpression memberObj && expr.Arguments[0] is ConstantExpression argConst)
{
- var constantValue=ContextExpressionsUtils.GetConstant(argConst);
+ var constantValue = ContextExpressionsUtils.GetConstant(argConst);
SetExpressionNodeAttributes(storageConfig, memberObj, constantValue, node, flatConfig);
}
else
diff --git a/sdk/src/Services/DynamoDBv2/Custom/DataModel/InternalModel.cs b/sdk/src/Services/DynamoDBv2/Custom/DataModel/InternalModel.cs
index f26161a1acfd..1f9e3e284d75 100644
--- a/sdk/src/Services/DynamoDBv2/Custom/DataModel/InternalModel.cs
+++ b/sdk/src/Services/DynamoDBv2/Custom/DataModel/InternalModel.cs
@@ -167,6 +167,11 @@ internal class PropertyStorage : SimplePropertyStorage
///
public bool IsAutoGeneratedTimestamp { get; set; }
+ ///
+ /// Behavior for handling updates to this property during a save operation.
+ ///
+ public UpdateBehavior UpdateBehaviorMode { get; set; }
+
// corresponding IndexNames, if applicable
public List IndexNames { get; set; }
@@ -246,6 +251,12 @@ public void Validate(DynamoDBContext context)
if (IsHashKey && IsRangeKey)
throw new InvalidOperationException("Property " + PropertyName + " cannot be both hash and range key");
+ if (UpdateBehaviorMode == UpdateBehavior.IfNotExists && (IsKey || IsVersion || IsCounter))
+ {
+ string propertyType = IsKey ? "key" : IsVersion ? "version" : IsCounter ? "counter" : "unknown";
+ throw new InvalidOperationException($"Property {PropertyName} cannot be a {propertyType} and have UpdateBehavior set to IfNotExists at the same time.");
+ }
+
if (ConverterType != null)
{
if (PolymorphicProperty)
@@ -290,6 +301,7 @@ internal PropertyStorage(MemberInfo member)
IndexNames = new List();
Indexes = new List();
FlattenProperties = new List();
+ UpdateBehaviorMode = UpdateBehavior.Always;
}
}
@@ -1111,6 +1123,11 @@ private static PropertyStorage MemberInfoToPropertyStorage(ItemStorageConfig con
config.HasAutogeneratedProperties = true;
}
+ if (propertyAttribute is DynamoDbUpdateBehaviorAttribute updateBehaviorAttribute)
+ {
+ propertyStorage.UpdateBehaviorMode = updateBehaviorAttribute.Behavior;
+ }
+
DynamoDBLocalSecondaryIndexRangeKeyAttribute lsiRangeKeyAttribute = propertyAttribute as DynamoDBLocalSecondaryIndexRangeKeyAttribute;
if (lsiRangeKeyAttribute != null)
{
diff --git a/sdk/src/Services/DynamoDBv2/Custom/DataModel/TransactWrite.cs b/sdk/src/Services/DynamoDBv2/Custom/DataModel/TransactWrite.cs
index 391c6e5d5df3..3d688ab556dc 100644
--- a/sdk/src/Services/DynamoDBv2/Custom/DataModel/TransactWrite.cs
+++ b/sdk/src/Services/DynamoDBv2/Custom/DataModel/TransactWrite.cs
@@ -1,17 +1,17 @@
/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
+* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+*
+* Licensed under the Apache License, Version 2.0 (the "License").
+* You may not use this file except in compliance with the License.
+* A copy of the License is located at
+*
+* http://aws.amazon.com/apache2.0
+*
+* or in the "license" file accompanying this file. This file is distributed
+* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+* express or implied. See the License for the specific language governing
+* permissions and limitations under the License.
+*/
using System;
using System.Collections.Generic;
@@ -227,7 +227,7 @@ public void AddSaveItem(T item)
SetNewVersion(storage);
AddDocumentTransaction(storage, conditionExpression);
-
+
var objectItem = new DynamoDBContext.ObjectWithItemStorage
{
OriginalObject = item,
@@ -446,23 +446,23 @@ private void AddDocumentTransaction(ItemStorage storage, Expression conditionExp
attributeNames.Remove(rangeKeyPropertyName);
}
+ var operationConfig = new TransactWriteItemOperationConfig
+ {
+ ConditionalExpression = conditionExpression,
+ ReturnValuesOnConditionCheckFailure = DocumentModel.ReturnValuesOnConditionCheckFailure.None
+ };
+
// If there are no attributes left, we need to use PutItem
// as UpdateItem requires at least one data attribute
if (attributeNames.Any())
{
- DocumentTransaction.AddDocumentToUpdate(storage.Document, new TransactWriteItemOperationConfig
- {
- ConditionalExpression = conditionExpression,
- ReturnValuesOnConditionCheckFailure = DocumentModel.ReturnValuesOnConditionCheckFailure.None
- });
+ var ifNotExistAttributeNames = DynamoDBContext.GetUpdateIfNotExistsAttributeNames(storage);
+ DocumentTransaction.AddDocumentToUpdate(storage.Document, ifNotExistAttributeNames, operationConfig);
+
}
else
{
- DocumentTransaction.AddDocumentToPut(storage.Document, new TransactWriteItemOperationConfig
- {
- ConditionalExpression = conditionExpression,
- ReturnValuesOnConditionCheckFailure = DocumentModel.ReturnValuesOnConditionCheckFailure.None
- });
+ DocumentTransaction.AddDocumentToPut(storage.Document, operationConfig);
}
}
@@ -569,4 +569,4 @@ private TracerProvider GetTracerProvider(List allTransactionPart
return tracerProvider;
}
}
-}
+}
\ No newline at end of file
diff --git a/sdk/src/Services/DynamoDBv2/Custom/DataModel/Utils.cs b/sdk/src/Services/DynamoDBv2/Custom/DataModel/Utils.cs
index 903a4d32092e..662045210c81 100644
--- a/sdk/src/Services/DynamoDBv2/Custom/DataModel/Utils.cs
+++ b/sdk/src/Services/DynamoDBv2/Custom/DataModel/Utils.cs
@@ -1,17 +1,17 @@
/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
+* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+*
+* Licensed under the Apache License, Version 2.0 (the "License").
+* You may not use this file except in compliance with the License.
+* A copy of the License is located at
+*
+* http://aws.amazon.com/apache2.0
+*
+* or in the "license" file accompanying this file. This file is distributed
+* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+* express or implied. See the License for the specific language governing
+* permissions and limitations under the License.
+*/
using System;
using System.Collections.Generic;
@@ -155,14 +155,14 @@ internal static void ValidateNumericType(Type memberType)
{
return;
}
- throw new InvalidOperationException("Version property must be of primitive, numeric, integer, nullable type (e.g. int?, long?, byte?)");
+ throw new InvalidOperationException("Version or counter property must be of primitive, numeric, integer, nullable type (e.g. int?, long?, byte?)");
}
internal static void ValidateTimestampType(Type memberType)
{
if (memberType.IsGenericType && memberType.GetGenericTypeDefinition() == typeof(Nullable<>) &&
(memberType.IsAssignableFrom(typeof(DateTime)) ||
- memberType.IsAssignableFrom(typeof(DateTimeOffset))))
+ memberType.IsAssignableFrom(typeof(DateTimeOffset))))
{
return;
}
@@ -210,7 +210,7 @@ internal static Type GetElementType(Type collectionType)
internal static bool ItemsToCollection([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicConstructors)] Type targetType, IEnumerable