Entity Framework Core Используйте пользовательский класс в запросе LINQC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Entity Framework Core Используйте пользовательский класс в запросе LINQ

Сообщение Anonymous »

Мы переходим от SQL Server в PostgreSQL. В SQL Server существует DateTimeOffset < /code> Тип столбца, но в PostgreSQL это недоступно, поэтому мы разделяем его на два столбца. (TimeStamptz) < /li>
Смещение в минутах (smallint) < /li>
< /ul>
Организация Ontity Framework Core 7 также поддерживает типы собственных объектов, которые i Я использую, чтобы сгруппировать столбцы в одном классе. Этот класс также имеет свойство [notmapped] dateTimeOffset , которое позволяет мне легко работать с датой в нашей логике.
К сожалению, я не могу использовать этот тип запрос LINQ. Это не может быть переведено с помощью EF Core.
Пример LINQ Запрос:
DateTime expiredDateTime = DateTime.UtcNow.AddDays(-30);
var items = context.ReceivedPackages.Where(i => i.ReceivedAt < expiredDateTime).ToList();

compackage class:
public class ReceivedPackage
{
public ReceivedPackage()
{
Identifier = Guid.NewGuid();
}

public Guid Identifier { get; set; }

public DbDateTime ReceivedAt { get; set; }
}

dbdatetime class:
[Owned]
public class DbDateTime
{
public DbDateTime()
{
}

public DbDateTime(DateTimeOffset value)
{
DateTimeOffset = value;
}

[NotMapped]
public DateTimeOffset DateTimeOffset
{
get => TimeOffsetHelper.CreateDateTimeOffset(DateTime, Offset);
set => (DateTime, Offset) = TimeOffsetHelper.ToUtcDateTimeAndOffset(value);
}

public DateTime DateTime { get; set; }
public short Offset { get; set; }

public virtual bool Equals(DateTime? other)
{
return other.HasValue && DateTime == other.Value;
}

// DbDateTime to DbDateTime comparisons
public static bool operator >(DbDateTime left, DbDateTime right)
{
if (left is null || right is null)
{
return false;
}
return left.DateTimeOffset > right.DateTimeOffset;
}

public static bool operator =(DbDateTime left, DbDateTime right)
{
if (left is null || right is null)
{
return false;
}
return left.DateTimeOffset >= right.DateTimeOffset;
}

public static bool operator right;
}

public static bool operator =(DbDateTime left, DateTime right)
{
if (left is null)
{
return false;
}
return left.DateTime >= right;
}

public static bool operator right.DateTime;
}

public static bool operator =(DateTime left, DbDateTime right)
{
if (right is null)
{
return false;
}
return left >= right.DateTime;
}

public static bool operator right;
}

public static bool operator =(DbDateTime left, DateTimeOffset right)
{
if (left is null)
{
return false;
}
return left.DateTimeOffset >= right;
}

public static bool operator right.DateTimeOffset;
}

public static bool operator =(DateTimeOffset left, DbDateTime right)
{
if (right is null)
{
return false;
}
return left >= right.DateTimeOffset;
}

public static bool operator i.ReceivedAt < expiredDateTime).ToList();

Метод расширения
public static IQueryable InterceptDbDateTimeExpressions(this IQueryable source)
{
var visitor = new DbDateTimeExpressionVisitor();
var newExpression = visitor.Visit(source.Expression);
return source.Provider.CreateQuery(newExpression);
}

dbdateTiMeexPressionVisitor:
public class DbDateTimeExpressionVisitor : ExpressionVisitor
{
protected override Expression VisitBinary(BinaryExpression node)
{
if (node.Left.Type == typeof(DbDateTime) && node.Right.Type == typeof(DbDateTime))
{
var left = Expression.Property(node.Left, nameof(DbDateTime.DateTime));
var right = Expression.Property(node.Right, nameof(DbDateTime.DateTime));
return Expression.MakeBinary(node.NodeType, left, right);
}
else if (node.Left.Type == typeof(DbDateTime) && node.Right.Type == typeof(DateTime))
{
var left = Expression.Property(node.Left, nameof(DbDateTime.DateTime));
return Expression.MakeBinary(node.NodeType, left, node.Right);
}
else if (node.Left.Type == typeof(DateTime) && node.Right.Type == typeof(DbDateTime))
{
var right = Expression.Property(node.Right, nameof(DbDateTime.DateTime));
return Expression.MakeBinary(node.NodeType, node.Left, right);
}
else if (node.Left.Type == typeof(DbDateTime) && node.Right.Type == typeof(DateTimeOffset))
{
var left = Expression.Property(node.Left, nameof(DbDateTime.DateTimeOffset));
return Expression.MakeBinary(node.NodeType, left, node.Right);
}
else if (node.Left.Type == typeof(DateTimeOffset) && node.Right.Type == typeof(DbDateTime))
{
var right = Expression.Property(node.Right, nameof(DbDateTime.DateTimeOffset));
return Expression.MakeBinary(node.NodeType, node.Left, right);
}

return base.VisitBinary(node);
}

protected override Expression VisitMember(MemberExpression node)
{
if (node.Member.DeclaringType == typeof(DbDateTime))
{
if (node.Member.Name == nameof(DbDateTime.DateTime))
{
return Expression.Property(node.Expression, nameof(DbDateTime.DateTime));
}
else if (node.Member.Name == nameof(DbDateTime.DateTimeOffset))
{
return Expression.Property(node.Expression, nameof(DbDateTime.DateTimeOffset));
}
}

return base.VisitMember(node);
}
}



Подробнее здесь: https://stackoverflow.com/questions/794 ... linq-query
Реклама
Ответить Пред. темаСлед. тема

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

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

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

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

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

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