Обнаружение и соответствующее преобразование выражений LinqC#

Место общения программистов C#
Ответить
Anonymous
 Обнаружение и соответствующее преобразование выражений Linq

Сообщение Anonymous »

Я написал метод расширения, чтобы упростить добавление многостолбцовых индексов в EF 8 (.NET 8) следующим образом:

Код: Выделить всё

public static IndexBuilder HasIndexUnique
(
this EntityTypeBuilder builder,
string indexName,
IEnumerable includeExpressions
) where TEntityType : class
{
if ((includeExpressions is null) || (!includeExpressions.Any()))
{
var currentMethod = MethodBase.GetCurrentMethod();
throw (new Exception($@"The method [{currentMethod?.DeclaringType?.FullName}.{currentMethod?.Name}] was called without any [{nameof(includeExpressions)}]."));
}

var propertyNames = includeExpressions
.Select
(
e =>
// Casting issue depending on what was sent in.
((MemberExpression) ((UnaryExpression) e.Body).Operand).Member.Name
)
.ToArray();

var indexBuilder = builder
.HasIndex
(
propertyNames,
$@"{indexName}"
)
.IsUnique(unique: true);

return (indexBuilder);
}
Встроенные перегрузки EntityTypeBuilder.HasIndex основаны на строках (что я считаю неуклюжим). Перегрузки, поддерживающие синтаксис Expression, допускают только один столбец. Вышеупомянутый метод работает как чудо и делает вызывающий код намного проще для чтения.

Код: Выделить всё

builder
.HasIndexUnique
(
"Index_IndexName_Unique",
e => e.ModelId,
e => e.ModelEntityPrincipleId,
e => e.ModelEntityDependentId,
e => e.ModelEntityBridgeId
);
В приведенном выше примере все переданные свойства имеют тип Int64. Когда я пытаюсь отправить свойство String, приведение выражения завершается неудачно.

Код: Выделить всё

builder.HasIndexUnique("Index_IndexName_Unique", e => e.Name);

// Exception at this line:
((MemberExpression) ((UnaryExpression) e.Body).Operand).Member.Name
System.InvalidCastException: 'Unable to cast object of type 'System.Linq.Expressions.PropertyExpression' to type 'System.Linq.Expressions.UnaryExpression'.'
Как обнаружить и обработать свойства разных типов, чтобы правильно их привести? Я уже предвижу несколько типов данных, и этого должно быть достаточно:

Код: Выделить всё

Int64, String, DateTime, Object, Byte []
Я был бы признателен за решение, но также хотел бы понять, что делает выражение Unary, Property или другие типы, которые я не исследовал.
РЕДАКТИРОВАТЬ:

Код: Выделить всё

public partial class ModelEntityRelationship:
IEntity
{
public virtual long Id { get; set; }
public virtual string Name { get; set; }

public virtual long ModelId { get; set; }
public virtual Model Model { get; set; }

public virtual long ModelEntityPrincipleId { get; set; }
public virtual ModelEntity ModelEntityPrinciple { get; set; } = new();

public virtual long ModelEntityDependentId { get; set; }
public virtual ModelEntity ModelEntityDependent { get; set; } = new();

public virtual long? ModelEntityBridgeId { get; set; }
public virtual ModelEntity? ModelEntityBridge { get; set; }
}
Я включаю исходный класс Entity, чтобы прояснить источник путаницы. Все объявления свойств идентичны, за исключением типов данных. Так почему же тип выражения изменится с Unary на Property при отправке объектов Int64 и String соответственно?

Подробнее здесь: https://stackoverflow.com/questions/791 ... ccordingly
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»