You don't tell LINQ to use the invariant culture. LINQ is only a collection of extension functions of the IEnumerable<T> and IQueryable<T> interfaces.
You are using a DbContext. It seems this is an Entity Framework DbContext, but even it is not, your DbContext is supposed to hide from you in what format numbers are stored in the storage (which is usually a SQL database, but doesn't have to be, it can be a CSV-file, EXCEL, JSon, whatever).
If you look closely to your object DbContext.Model, you'll see that the class of this object implements IQueryable<Model>.
This means, that this object can hold two things: an Expression and a 'Provider'. (ok, also an elementType, in your example this will be Model, not meaningful in this discussion)
When you use DbContext.Model as the starting point of your query, you are in fact changing the Expression inside the IQueryable<Model>. As long as you are not asking for the first element in of your sequence of models the Provider is not used.
The Provider hides from you how your sequence of Models is stored. The Provider knows whether it is a relational database, or a CSV-file, or whatever. It is the task of the Provider to translate the Expression into a format that the storage understands and fetch the data from the storage.
For Entity Framework DbContexts, this usually means that the storage is a SQL(-like) database. The Provider knows the database model and it knows how to translate your Expression into SQL and how to communicate with your database.
After reading this, you should understand, that the user of you DbContext.Model object should not be aware in what format the storage saves decimals. It is the task of the Provider to translate decimals into storage format. And if this storage format stores decimals as Spanish strings, then the Provider should translate decimals into Spanish strings.
Now back to your question, because this knowledge does not solve your problem.
You should investigate why the Spanish notation seeps through to your DbContext.Models
It seems that the storage of your database was told to store Length as a string instead of a decimal.
If your database would be SQL, then a decimal would not have been saved as a string, but as a value with a certain precision.
If the database saves your Length as a string, then the designer of your database told entity framework that Model.Length is a string, not a decimal. In that case, the definition of your Model class does not correctly represent the contents of your Model table in the database. Model.Length should not be a decimal, but a string, thus representing the structure of your database Model table
The neat solution would be to change the Length column in your database from string to value-with-precision (whatever database you are using). If you can't change the structure of the Model table you database, you should change your Model class such that it represents your model:
class Model
{
public string Description {get; set;}
public string Length {get; set;}
private static IFormatProvider spanishCulture = CultureInfo.CreateSpecificCulture("es-ES");
[NotMapped]
public decimal LengthInMeters
{
get {return Decimal.Parse(this.Length, spanishCulture);}
set {this.Length = value.ToString(spanishCulture); }
}
}
This would also solve the problem of the unknown unit of length (m? cm? inch?)
An even cleaner solution, where you let your Model class exactly represent the database table, would be to create a SpanishModel class and create extension functions to convert from Model to SpanishModel and back
// model represents exactly database table:
class Model
{
public string Description {get; set;}
public string Length {get; set;}
}
class SpanishModel
{
public string Description {get; set;}
public decimal Length {get; set;}
}
// extension functions of model:
static class ModelExtensions
{
private static IFormatProvider spanishCulture = CultureInfo.CreateSpecificCulture("es-ES");
public static SpanishModel AsSpanishModel(this Model model)
{
return new SpanishModel()
{
Description = model.Description,
Length = Decimal.Parse(model.Length, spanishCulture);
}
}
public static Model AsModel(this SpanishModel model)
{
return new Model()
{
description = model.Description,
Length = model.Length.ToString(spanishCulture),
};
}
public static IEnumerable<SpanishModel> AsSpanishModels(this IEnumerable<Model> models)
{
return models.Select(model => model.AsSpanishModel();
}
public static IEnumerable<SpanishModel> AsModels(this IEnumerable<SpanishModel> models)
{
return models.Select(model => model.AsModel();
}
}
Usage:
IEnumerable<SpanishModel> requestedModels = myDbContext.Models
.Where(model => model.Description == ...)
.AsSpanishModels();
See Extension Functions Demystified
If you really want to hide the fact that SpanishModels are not part of your database, consider extending your DbContext class:
static class MyDbContextExtensions
{
public static IQueryable<SpanishModel> SpanishModel(this MyDbContext dbContext)
{
return dbContext.Models.AsSpanishModels();
}
}
usage:
using (var myDbContext = new MyDbContext(...))
{
IQueryable<SpanishModel> tallSpanishModels = myDbContext.SpanishModels
.Where(model => model.Length > 1.85M);
foreach (SpanishModel tallModel in tallSpanishModels)
{
Console.WriteLine($"{tallModel.Description} has a length of {tallModel.Length}";
}
}
You almost can't see any difference between other DbSets of your DbContext and your SpanishModel. Come to think of it, I think this is the neatest solution.