Мы переходим от 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
Entity Framework Core Используйте пользовательский класс в запросе LINQ ⇐ C#
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Entity Framework Core «один к нулю или один», не привязывая включенные отношения при запросе
Anonymous » » в форуме C# - 0 Ответы
- 32 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Entity Framework Core «один к нулю или один», не привязывая включенные отношения при запросе
Anonymous » » в форуме C# - 0 Ответы
- 30 Просмотры
-
Последнее сообщение Anonymous
-