'[EFCore 5, SQLite3]: how to create table without ROWID
I have a model with non-integer primary key. TEXT can't be a alias for ROWID and sqlite creates a ROWID column automatically. I can disable ROWID when I make a scheme manually, but in EF I do not know how to do it.
EF creates table like this:
CREATE TABLE text_data (
id TEXT NOT NULL PRIMARY KEY,
text TEXT NOT NULL
);
But I want to table be like this:
CREATE TABLE text_data (
id TEXT NOT NULL PRIMARY KEY,
text TEXT NOT NULL
) WITHOUT ROWID;
What can I tell EF to disable ROWID?
Solution 1:[1]
public class MyRelationalCommandBuilder : RelationalCommandBuilder
{
static readonly String _beginCreateTable = "CREATE TABLE";
static readonly String _endCreateTable = ");";
static readonly String _withoutRowId = ") WITHOUT ROWID;";
public MyRelationalCommandBuilder(RelationalCommandBuilderDependencies dependencies) : base(dependencies)
{
}
public override IRelationalCommand Build() => new RelationalCommand(Dependencies, _fixCreateTableCommand(), Parameters);
String _fixCreateTableCommand()
{
String originalCommandText = base.ToString();
Int32 startCreateTableIndex = originalCommandText.IndexOf(_beginCreateTable);
if (startCreateTableIndex < 0 || originalCommandText.Contains(_withoutRowId) || originalCommandText.Contains("AUTOINCREMENT"))
return originalCommandText;
Int32 endCreateTableIndex = originalCommandText.IndexOf(_endCreateTable, startCreateTableIndex);
String createTableSubstring = originalCommandText.Substring(startCreateTableIndex, endCreateTableIndex - startCreateTableIndex + _endCreateTable.Length);
String newCreateTableSubstring = createTableSubstring.Replace(_endCreateTable, _withoutRowId);
String newCommandText = originalCommandText.Replace(createTableSubstring, newCreateTableSubstring);
return newCommandText;
}
}
public class MyRelationalCommandBuilderFactory : RelationalCommandBuilderFactory
{
public MyRelationalCommandBuilderFactory(RelationalCommandBuilderDependencies dependencies) : base(dependencies)
{
}
public override IRelationalCommandBuilder Create() => new MyRelationalCommandBuilder(Dependencies);
}
public class MyDbContext : DbContext
{
protected void OnConfiguring(DbContextOptionsBuilder optionsBuilder, String dbFilePath)
{
base.OnConfiguring(optionsBuilder);
optionsBuilder
.UseSqlite()
.ReplaceService<IRelationalCommandBuilderFactory, MyRelationalCommandBuilderFactory>();
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
