Saltar al contenido

Convertir fecha y hora a un formato string dentro de una consulta LINQ-to-entities

Después de buscar en varios repositorios y foros al final hemos hallado la resolución que te mostraremos ahora.

Solución:

Otra opción es usar SqlFunctions.DateName, tu código será así:

var offer = (from p in dc.CustomerOffer
                 join q in dc.OffersInBranch
                     on p.ID equals q.OfferID
                 where q.BranchID == singleLoc.LocationID
                 let value = (p.OriginalPrice - p.NewPrice) * 100 / p.OriginalPrice
                 orderby value descending
                 select new
                 
                     Title = p.OfferTitle,
                     Description = p.Description,
                     BestOffer = value,
                     ID = p.ID,
                     LocationID = q.BranchID,
                     LocationName = q.CustomerBranch.BranchName,
                     OriginalPrice = SqlFunctions.StringConvert((decimal)p.OriginalPrice),
                     NewPrice = SqlFunctions.StringConvert((decimal)p.NewPrice),
                     StartDate = SqlFunctions.DateName("day", p.StartDate) + "/" + SqlFunctions.DateName("month", p.StartDate) + "/" +  SqlFunctions.DateName("year", p.StartDate)
                 )

Lo encontré útil si no desea agregar un nuevo bloque de selección adicional.

EDITAR: ahora que entiendo la pregunta, le doy otra oportunidad 🙂

var offer = (from p in dc.CustomerOffer
                     join q in dc.OffersInBranch
                         on p.ID equals q.OfferID
                     where q.BranchID == singleLoc.LocationID
                     let value = (p.OriginalPrice - p.NewPrice) * 100 / p.OriginalPrice
                     orderby value descending
                     select new
                     
                         Title = p.OfferTitle,
                         Description = p.Description,
                         BestOffer=value,
                         ID=p.ID,
                         LocationID=q.BranchID,
                         LocationName=q.CustomerBranch.BranchName,
                         OriginalPrice=SqlFunctions.StringConvert((decimal)p.OriginalPrice),
                         NewPrice=SqlFunctions.StringConvert((decimal)p.NewPrice),
                         StartDate=p.StartDate

                     )
                     .ToList()
                     .Select(x => new Offer()
                     
                         Title = x.OfferTitle,
                         Description = x.Description,
                         BestOffer=value,
                         ID=x.ID,
                         LocationID=x.BranchID,
                         LocationName=x.CustomerBranch.BranchName,
                         OriginalPrice=x.OriginalPrice,
                         NewPrice=x.NewPrice,
                         StartDate=x.StartDate.ToString("dd.MM.yy")
                     ).First();

Sé que es un poco largo, pero ese es el problema con Linq To SQL.

Cuando usa linq, la llamada a la base de datos no se ejecuta hasta que usa algo como ToList() o First() que da como resultado objetos reales. Una vez que esa llamada SQL se ejecuta con la primera llamada .First(), ahora está trabajando con tipos .NET y puede usar cosas de DateTime.

Terminé usando la función sql FORMAT; aquí hay una versión simplificada de esta implementación:

https://weblogs.asp.net/ricardoperes/registering-sql-server-built-in-functions-to-entity-framework-code-first

Primero necesitas definir la función en EF:

public class FormatFunctionConvention : IStoreModelConvention

    public void Apply(EdmModel item, DbModel model)
    
        var payload = new EdmFunctionPayload
        
            StoreFunctionName = "FORMAT",
            Parameters = new[] 
                FunctionParameter.Create("value", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.DateTime), ParameterMode.In),
                FunctionParameter.Create("format", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), ParameterMode.In)
            ,
            ReturnParameters = new[] 
                FunctionParameter.Create("result", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), ParameterMode.ReturnValue)
            ,
            Schema = "dbo",
            IsBuiltIn = true
        ;

        item.AddItem(EdmFunction.Create("FORMAT", "CodeFirstDatabaseSchema", item.DataSpace, payload, null));
    

Luego defínalo como métodos C#:

public static class SqlFunctions

    [DbFunction("CodeFirstDatabaseSchema", "FORMAT")]
    public static String Format(this DateTime value, string format)
    
        return value.ToString(format);
    

    [DbFunction("CodeFirstDatabaseSchema", "FORMAT")]
    public static String Format(this DateTime? value, string format)
    
        return value?.ToString(format);
    

Registralo en tu DbContext:

public class SqlDb : DbContext

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    
        base.OnModelCreating(modelBuilder);
        modelBuilder.Conventions.Add(new FormatFunctionConvention());
    

Y finalmente, puedes llamarlo así:

var x = db.MyItems.Select(i => new  FormattedDate = SqlFunctions.Format(i.MyDate, "MM/dd/yyyy") ).ToArray();

Te mostramos comentarios y puntuaciones

Si estás de acuerdo, tienes la libertad de dejar una sección acerca de qué le añadirías a esta reseña.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *