Фон
У меня есть такая модель стола:
public class Book
{
[Key]
public Guid Id { get; set; }
public string Name { get; set; } = default!;
public string Author { get; set; } = default!;
public int Pages { get; set; } = default!;
}
Если я запустил команду добавления миграции
dotnet ef migrations add AddBooks -p .\MyApplication.Infrastructure\ -s .\MyApplication.API\
Я получаю ожидаемый результат:
migrationBuilder.CreateTable(
name: "Books",
columns: table => new
{
Id = table.Column<Guid>(type: "RAW(16)", nullable: false),
Name = table.Column<string>(type: "NVARCHAR2(2000)", nullable: false),
Author = table.Column<string>(type: "NVARCHAR2(2000)", nullable: false),
Pages = table.Column<int>(type: "NUMBER(10)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Books", x => x.Id);
});
Если я затем обновлю базу данных:
dotnet ef database update -p .\MyApplication.Infrastructure\ -s .\MyApplication.API\
Таблица создается, как указано:
Где все идет не так
Я ожидаю увидеть, что могу запросить свою таблицу следующим образом:
select * from Books b
Однако там указано, что Table or view does not exist.
Если я создаю свой запрос, он делает это следующим образом:
select * from "Books" b
Это работает правильно, но отличается от того, как настроены все остальные таблицы.
Мой вопрос
Как я могу создать свои таблицы без необходимости использования этих дополнительных двойных кавычки?





Oracle чувствителен к регистру. Однако по умолчанию все идентификаторы, не заключенные в кавычки, преобразуются в верхний регистр, чтобы они выглядели нечувствительными к регистру. Поэтому:
select * from Books
select * from books
select * from BoOkS
select * from BOOKS
Все они будут выбраны из таблицы под названием BOOKS (заглавные буквы) и эквивалентны.
Идентификаторы в кавычках используются для обеспечения учета регистра в идентификаторе. Поэтому:
select * from "Books"
select * from "books"
select * from "BoOkS"
select * from "BOOKS"
Будет выбирать из четырех разных таблиц — Books, books, BoOkS и BOOKS соответственно, и только последний запрос является эквивалентом запросов с использованием идентификаторов без кавычек.
Когда вы создаете миграцию, вы создаете таблицу с именем Books (в смешанном регистре). Это означает, что если вы хотите получить к ней доступ, вам нужно будет использовать идентификатор в кавычках с точным регистром:
select * from "Books"
Альтернативно вам необходимо изменить код EF, чтобы при миграции генерировались идентификаторы в верхнем регистре:
[Table("BOOKS")]
public class Book
{
[Key]
[Column("ID")]
public Guid Id { get; set; }
[Column("NAME")]
public string Name { get; set; } = default!;
[Column("AUTHOR")]
public string Author { get; set; } = default!;
[Column("PAGES")]
public int Pages { get; set; } = default!;
}
Тогда вы сможете использовать идентификаторы без кавычек (в любом случае) в своих запросах.
В противном случае посмотрите, есть ли параметр миграции, который изменит регистр всех идентификаторов на верхний регистр, чтобы вы могли использовать идентификаторы без кавычек.
Приложение
Если вы добавите пакет nuget
EFCore.NamingConventions
в проект, который содержит ваш DbContext и переопределить OnConfiguring, вы можете сделать следующее:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseUpperSnakeCaseNamingConvention();
base.OnConfiguring(optionsBuilder);
}
Это приведет к созданию таблицы Books следующим образом:
migrationBuilder.CreateTable(
name: "BOOKS",
columns: table => new
{
ID = table.Column<Guid>(type: "RAW(16)", nullable: false),
NAME = table.Column<string>(type: "NVARCHAR2(2000)", nullable: false),
AUTHOR = table.Column<string>(type: "NVARCHAR2(2000)", nullable: false),
PAGES = table.Column<int>(type: "NUMBER(10)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_BOOKS", x => x.ID);
});
@kbd Я не знаю ответа на настройки миграции, однако, если вы посмотрите документацию Использование операции миграции, там приведен пример того, как переопределить сгенерированный SQL, и пример включает строку .Append(sqlHelper.DelimitIdentifier(operation.Name)), если это был изменен на .Append(operation.Name), тогда сгенерированный запрос будет использовать идентификаторы без кавычек (но также может быть уязвим для SQL-инъекций). ...
Вам необходимо выяснить, возможно ли что-то подобное для таблиц (и понять последствия).
Я нашел это. Я отредактировал ваш ответ, чтобы иметь единственное решение.
@kbd Я просто добавлял что-то подобное, однако ваше редактирование было немного более полным.
Это было легко... Я бы предпочел настройку миграции, а не необходимость аннотировать все вручную. Я пока воздержусь от ответа в надежде, что кто-то (или вы) сможет предоставить эту информацию. (Если это займет слишком много времени, я просто приму)