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.