I'm using EF Core 1.1 and it's doubling the column length at the database.
entityBuilder.Property(t => t.Name)
.HasMaxLength(200)
.IsRequired();
The code above generate the following script
Name = table.Column<string>(maxLength: 200, nullable: false)
But when I update the database, it generate the following result
Any ideas ?
One char is two bytes in your encoding
Related
I am using Postgresql. My Yii2 code for the update is
ModelName::updateAll(['my_column' => "REPLACE(my_column1,'removed_','')"]);
Actual query is
update my_table set my_column = REPLACE(my_column1,'removed_','');
When I run my yii2 code it shows the error
SQLSTATE[22001]: String data, right truncated: 7 ERROR: value too long for type character varying(50)
The SQL being executed was: UPDATE "my_table" SET "my_column1"='REPLACE(my_column1,''removed_'','''')'
If you use ['column' => 'value'] syntax for attributes the framework expects that values of array are simple values and treats them accordingly. That's why your expression gets converted to string value instead of using as expression.
If you want to avoid that you need to wrap your values in yii\db\Expression like this:
ModelName::updateAll([
'my_column' => new \yii\db\Expression("REPLACE(my_column1,'removed_','')")
]);
I need set start value (100000000) for PK 'ProductID'. I use this code:
modelBuilder.Entity<Product>().Property(x => x.ProductID).UseIdentityColumn(100000000, 1);
but in DB the value of new records is still 1,2,3
In a SQL Server database I have a column of decimal datatype defined something like this:
CREATE TABLE MyTable
(
Id INT,
Number DECIMAL(9, 4)
)
I use Entity Framework and I would like to return column Number converted to a string with only the digits right of the decimal separator that are actually needed. A strict constraint is that a result must be an IQueryable.
So my query is:
IQueryable queryable = (
from myTable in MyDatabase.NyTable
select new
{
Id = myTable.Id,
Number = SqlFunctions.StringConvert(myTable.Number,9,4)
}
);
The problem with is that it always convert number to string with 4 decimals, even if they are 0.
Examples:
3 is converted to "3.0000"
1.2 is converted to "1.2000"
If I use other parameters for StringConvert i.e.
SqlFunctions.StringConvert(myTable.Number, 9, 2)
the results are also not OK:
0.375 gets rounded to 0.38.
StringConvert() function is translated into SQL Server function STR.
https://learn.microsoft.com/en-us/sql/t-sql/functions/str-transact-sql?view=sql-server-2017
This explains the weird results.
In the realm of Entity Framework and LINQ I was not able to find a working solution.
What I look for is something like C# function
String.Format("0.####", number)
but this cannot be used in a LINQ query.
In plain simple SQL I could write my query like this
SELECT
Id,
Number = CAST(CAST(Number AS REAL) AS VARCHAR(15))
FROM
MyTable
I have not managed to massage LINQ to produce query like that.
A workaround would be to forget doing this in LINQ, which is quite inflexible and messy thing, borderline on useless and just return type DECIMAL from database and do my formatting on a client side before displaying. But this is additional, unnecessary code and I would hate to di it that way if there perhaps is a simpler way via LINQ.
Is it possible to format numbers in LINQ queries?
I would absolutely return a decimal from he database and format it when needed. Possible directly after the query. But usually this is done at display time to take into account culture specific formatting from the the client.
var q =
(from myTable in MyDatabase.NyTable
select new
{
Id = myTable.Id,
Number = myTable.Number
})
.AsEnumerable()
.Select(x => new { Id = x.Id, Number = x.Number.ToString("G29") });
I'm trying to find a way to implement a Linq-to-Entities compiled query of the form:
Func<MyEntities, List<int>, IQueryable<MyClass>> query = System.Data.Objects.CompiledQuery.Compile(
(MyEntities entities, List<int> IDs) => (
(from au in entities.Mine where IDs.Any(x => x == au.ID) select au)
));
Because only scalar parameters can be passed to CompiledQuery.Compile the above fails. I'm trying to find some clever way to pass a comma delimited list of integers as a string and use that in the L2E query along the lines of:
Func<MyEntities, string, IQueryable<MyClass>> query = System.Data.Objects.CompiledQuery.Compile(
(MyEntities entities, string IDs) => (
(from au in entities.Mine where IDs.Split(',').Any(x => Convert.ToInt32(x) == au.ID) select au)
));
But that doesn't work due to the unsupported Split function.
Any clever ideas about how this could be implemented?
I'm not sure if this could possibly work, but maybe try to use join of List<int> IDs and MyEntities entities?
I ended up finding a way to do it but it's way too slow at around 3s.
string ids = "|" + String.Join("|", new List<int> { 4, 5, 6, 7, 8, 9, 10, 20, 23, 34 }) + "|";
Func<MyEntities, string, IQueryable<MyClass>> query = System.Data.Objects.CompiledQuery.Compile(
(MyEntities entities, string IDs) => (
(from au in entities.Mine where IDs.Contains("|" + SqlFunctions.StringConvert((decimal)au.ID).Trim() + "|")select au)
));
Back to the drawing board.
You can't.
What does CompiledQuery do? It pre-converts the query to a canonical command tree -- an intermediate representation used to generate SQL by the provider.
The SQL for a command with a scalar param is the same structure regardless of the param value. But the SQL generated for, say, a list of 2 items will be structurally different from the SQL afor a list of 3 items, because it takes one fewer OR predicate in its WHERE clause. Most DB servers won't take lists as a param value, after all.
Your string/| kludge works because you're now passing only one param, not a list, to the DB server. But as you've seen, the server can't index such a query, so it will be slow.
I have a table with a DateTime "TimeStamp" column and an int "TimeoutSeconds" column. I want to retrieve all records from this table where DateTime.Now - TimeStamp > TimeoutSeconds. In a stored proc this was a no brainer using GetDate():
select * from Schema.TableName mp
where (GetDate() - mp.[Timestamp]) > mp.Timeout
However, with Entity Framework using either LINQ syntax or Lambda I cannot do this because it seems the Lambda input variable (mp) cannot be used as part of a calculation only as part of a predicate, so this does not compile:
var records = context.TableName.Where(mp => (DateTime.Now - mp.TimeStamp) > mp.Timeout);
This does not compile.
I don't want to retrieve the whole table then do my filtering in memory and would rather not use a stored proc or Entity SQL. What are my options here?
This does not compile because you are comparing (DateTime.Now - mp.TimeStamp) which has return type System.TimeSpan to int. The first solution that comes to mind is to do
Where(mp => (DateTime.Now - mp.TimeStamp) > new TimeSpan(0, 0, 0, mp.Timeout))
Unfortunately this doesn't seem to work in EF, so if you have MS SQL Server as the DB, you can use SqlFunctions in EF4:
var records = context.
TableName.
Where(mp => System.Data.Objects.SqlClient.SqlFunctions.
DateDiff("s", mp.TimeStamp, DateTime.Now) > mp.Timeout);
http://msdn.microsoft.com/en-us/library/dd487052.aspx