Недавно я попытался разобраться в базе данных с альтернативным отношением ключей, используя C# Entity Framework Core и SQL Server, и был удивлен, что я не смог развернуть схему базы данных без ручных изменений. См. Минимальную настройку базы данных ниже: < /p>
Минимальная настройка базы данных < /p>
Здесь, принципиальные, имеют два ключа: первичный ключ и альтернативный ключ. Зависимая таблица зависит от альтернативного ключа принципиального. Если я попытаюсь справиться с этим с помощью основного ядра 9.0.2 на .net 8 и SQL Server 2022, я должен вручную определить альтернативный ключ в проекте Target C# для правильного развертывания, даже если ключ назван в соответствии с Конвенция. Вместе с пустым проектом C# с правильными пакетами NUGET
[*] Run Dotnet EF DBContext Scaffold "" Microsoft.entityFrameWorkCore.sqlServer для каркаса базы данных
< /ul>
Это приводит к тому, что следующий код генерируется к MinimalReProduceContext.cs: < /p>
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
namespace MinimalReproduce.Scaffold;
public partial class MinimalReproduceContext : DbContext
{
public MinimalReproduceContext()
{
}
public MinimalReproduceContext(DbContextOptions options)
: base(options)
{
}
public virtual DbSet DependentTables { get; set; }
public virtual DbSet
PrincipalTables { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see https://go.microsoft.com/fwlink/?LinkId=723263.
=> optionsBuilder.UseSqlServer("");
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity(entity =>
{
entity.HasKey(e => e.DependentId);
entity.ToTable("DependentTable");
entity.Property(e => e.DependentId).ValueGeneratedNever();
entity.HasOne(d => d.Alternate).WithMany(p => p.DependentTables)
.HasPrincipalKey(p => p.AlternateId)
.HasForeignKey(d => d.AlternateId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_DependentTable_PrincipalTable");
});
modelBuilder.Entity(entity =>
{
entity.HasKey(e => e.PrimaryId);
entity.ToTable("PrincipalTable");
entity.HasIndex(e => e.AlternateId, "AK_PrincipalTable_AlternateId").IsUnique();
entity.Property(e => e.PrimaryId).ValueGeneratedNever();
});
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
< /code>
Я бы ожидал, что efcore обнаружит альтернативный ключ, особенно потому, что ключ назван в соответствии с соглашением о альтернативном ключе, найденном здесь. Я ожидаю, что сгенерированный контекст содержит что -то вроде объекта (). Hasalternatekey (e => e.alternateid)
, но вместо этого существует только объект. ) .IsUnique () . Если я продолжите: < /p>
Удалить существующую настройку минимальной базы данных из SQL Server < /li>
Failed executing DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='0']
CREATE UNIQUE INDEX [AK_PrincipalTable_AlternateId] ON [PrincipalTable] ([AlternateId]);
Microsoft.Data.SqlClient.SqlException (0x80131904): The operation failed because an index or statistics with name 'AK_PrincipalTable_AlternateId' already exists on table 'PrincipalTable'.
at Microsoft.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs:line 2010
at Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) in /_/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs:line 770
at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs:line 1421
at Microsoft.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs:line 2637
at Microsoft.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean isAsync, Int32 timeout, Boolean asyncWrite) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs:line 3502
at Microsoft.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry, String methodName) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs:line 1667
at Microsoft.Data.SqlClient.SqlCommand.ExecuteNonQuery() in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs:line 1213
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQuery(RelationalCommandParameterObject parameterObject)
at Microsoft.EntityFrameworkCore.Migrations.MigrationCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.Execute(IReadOnlyList`1 migrationCommands, IRelationalConnection connection, MigrationExecutionState executionState, Boolean beginTransaction, Boolean commitTransaction, Nullable`1 isolationLevel)
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.c.b__3_1(DbContext _, ValueTuple`6 s)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQuery(IReadOnlyList`1 migrationCommands, IRelationalConnection connection, MigrationExecutionState executionState, Boolean commitTransaction, Nullable`1 isolationLevel)
at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.MigrateImplementation(DbContext context, String targetMigration, MigrationExecutionState state, Boolean useTransaction)
at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.c.b__20_1(DbContext c, ValueTuple`4 s)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String connectionString, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(String targetMigration, String connectionString, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.c__DisplayClass0_0.b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
ClientConnectionId:bdd08de7-8eb9-4603-bb01-6637b3998c78
Error Number:1913,State:1,Class:16
The operation failed because an index or statistics with name 'AK_PrincipalTable_AlternateId' already exists on table 'PrincipalTable'.
Есть ли что -то, что мне не хватает, чтобы сделать эту работу без ручного вмешательства?
Недавно я попытался разобраться в базе данных с альтернативным отношением ключей, используя C# Entity Framework Core и SQL Server, и был удивлен, что я не смог развернуть схему базы данных без ручных изменений. См. Минимальную настройку базы данных ниже: < /p> Минимальная настройка базы данных < /p> Здесь, принципиальные, имеют два ключа: первичный ключ и альтернативный ключ. Зависимая таблица зависит от альтернативного ключа принципиального. Если я попытаюсь справиться с этим с помощью основного ядра 9.0.2 на .net 8 и SQL Server 2022, я должен вручную определить альтернативный ключ в проекте Target C# для правильного развертывания, даже если ключ назван в соответствии с Конвенция. Вместе с пустым проектом C# с правильными пакетами NUGET [*] Run Dotnet EF DBContext Scaffold "" Microsoft.entityFrameWorkCore.sqlServer для каркаса базы данных < /ul> Это приводит к тому, что следующий код генерируется к MinimalReProduceContext.cs: < /p> [code]using System; using System.Collections.Generic; using Microsoft.EntityFrameworkCore;
namespace MinimalReproduce.Scaffold;
public partial class MinimalReproduceContext : DbContext { public MinimalReproduceContext() { }
public MinimalReproduceContext(DbContextOptions options) : base(options) { }
public virtual DbSet DependentTables { get; set; }
public virtual DbSet PrincipalTables { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) #warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see https://go.microsoft.com/fwlink/?LinkId=723263. => optionsBuilder.UseSqlServer("");
partial void OnModelCreatingPartial(ModelBuilder modelBuilder); } < /code> Я бы ожидал, что efcore обнаружит альтернативный ключ, особенно потому, что ключ назван в соответствии с соглашением о альтернативном ключе, найденном здесь. Я ожидаю, что сгенерированный контекст содержит что -то вроде объекта (). Hasalternatekey (e => e.alternateid) [/code], но вместо этого существует только объект. ) .IsUnique () . Если я продолжите: < /p> [list] Удалить существующую настройку минимальной базы данных из SQL Server < /li> [code]dotnet ef migrations add Initial[/code] для создания начальной миграции [*][code]dotnet ef database update[/code] для развертывания базы данных [/list] Эта последняя команда, затем ошибки с следующим сообщением: [code]Failed executing DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='0'] CREATE UNIQUE INDEX [AK_PrincipalTable_AlternateId] ON [PrincipalTable] ([AlternateId]); Microsoft.Data.SqlClient.SqlException (0x80131904): The operation failed because an index or statistics with name 'AK_PrincipalTable_AlternateId' already exists on table 'PrincipalTable'. at Microsoft.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs:line 2010 at Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) in /_/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlInternalConnection.cs:line 770 at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs:line 1421 at Microsoft.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs:line 2637 at Microsoft.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean isAsync, Int32 timeout, Boolean asyncWrite) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs:line 3502 at Microsoft.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry, String methodName) in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs:line 1667 at Microsoft.Data.SqlClient.SqlCommand.ExecuteNonQuery() in /_/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs:line 1213 at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQuery(RelationalCommandParameterObject parameterObject) at Microsoft.EntityFrameworkCore.Migrations.MigrationCommand.ExecuteNonQuery(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues) at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.Execute(IReadOnlyList`1 migrationCommands, IRelationalConnection connection, MigrationExecutionState executionState, Boolean beginTransaction, Boolean commitTransaction, Nullable`1 isolationLevel) at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.c.b__3_1(DbContext _, ValueTuple`6 s) at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded) at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQuery(IReadOnlyList`1 migrationCommands, IRelationalConnection connection, MigrationExecutionState executionState, Boolean commitTransaction, Nullable`1 isolationLevel) at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.MigrateImplementation(DbContext context, String targetMigration, MigrationExecutionState state, Boolean useTransaction) at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.c.b__20_1(DbContext c, ValueTuple`4 s) at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded) at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration) at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String connectionString, String contextType) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(String targetMigration, String connectionString, String contextType) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.c__DisplayClass0_0.b__0() at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action) ClientConnectionId:bdd08de7-8eb9-4603-bb01-6637b3998c78 Error Number:1913,State:1,Class:16 The operation failed because an index or statistics with name 'AK_PrincipalTable_AlternateId' already exists on table 'PrincipalTable'. [/code] Есть ли что -то, что мне не хватает, чтобы сделать эту работу без ручного вмешательства?
Недавно я пытался оснастить базу данных с альтернативным отношением ключей, используя C#, Entity Framework Core и SQL Server, я был удивлен, что не смог развернуть схему базы данных без ручных изменений. См. Минимальная настройка базы данных ниже:...
В моем проекте была создана система журналирования для регистрации всех действий в приложении. Теперь, когда мы создаем .xcframework для регистратора, я вижу, что добавляется ссылка на Metal framework; что делает невозможным запуск приложения на...
Я стараюсь избегать вызова SaveChanges внутри цикла и вызывать его только один раз, когда цикл завершается.
Похоже, что в этом случае мне приходится вызывать SaveChanges на каждой итерации, вот небольшой пример.
У меня есть два объекта:
public class...
Есть ли способ получить все изменения, внесенные в объект в Entity Framework, прежде чем он сохранит все изменения. Причина этого в том, что я хочу создать таблицу журнала в базе данных наших клиентов:
У нас есть небольшой фрагмент кода, использующий сноупарк и Python, который можно запустить изнутри Snowflake. Нам необходимо получать данные от пользователя для специальных запусков вручную.
Например, рассмотрим код, который принимает start_date и...