MS has documentation for EF Core + Azure SQL with Managed Identity. This SO post from two years ago also had an in-depth discussion regarding it along with some alternative implementations.
But I cannot find anything for Azure PostgreSQL, which also supports managed identity, for use with EF Core.
MS has a generic documentation for Azure PostgreSQL managed identity here:
https://learn.microsoft.com/en-us/azure/postgresql/howto-connect-with-managed-identity
It seems to suggest that replacing the password with access token in a regular PostgreSQL connection string is how it works.
So what is the best way to implement this with EF Core?
Any advice or link to related documentations would be greatly appreciated.
replacing the password with access token in a regular PostgreSQL connection string is how it works.
In .NET Core that would typically be configured something like this:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddTransient(typeof(Foo));
services.AddSingleton(typeof(Bar));
services.AddDbContext<Db>((sp, options) =>
{
var config = sp.GetRequiredService<IConfiguration>();
var constr = config.GetConnectionString("ConnectionString");
var tp = sp.GetService<ITokenProvider>();
var token = tp.GetToken("https://ossrdbms-aad.database.windows.net");
constr = constr.Replace("[passsword]", token);
options.UseNpgsql(constr);
});
}
Related
I am trying to migrate my asp.net core application from using Azure SQL database to use CosmosDB database.
Facing an issue when trying to create collections with the following error messages:
System.InvalidOperationException: 'The entity type 'IdentityRole' has
property 'ConcurrencyStamp' as its concurrency token, but only '_etag'
is supported. Consider using 'EntityTypeBuilder.UseETagConcurrency'.'
I have tried these changes, none of them solve the issue.
I added UseETagConcurrency when building the model
builder.Entity<IdentityRole>().ToContainer("Roles").UseETagConcurrency();
I create new derived class from IdentityRole, added _etag
property to Role model
Any ideas on how to resolve this issue?
Thank you for your assistance.
Figured it out! The issue is Role & User already have a concurrency token which is stored in the property 'ConcurrencyStamp'. So we need to tell EF that this property is what we want to use for the Etag concurrency. So instead of using UseETagConcurrency() use the following:
builder.Property(d => d.ConcurrencyStamp)
.IsETagConcurrency();
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<IdentityRole>()
.Property(b => b.ConcurrencyStamp)
.IsETagConcurrency();
builder.Entity<ApplicationUser>() // ApplicationUser mean the Identity user 'ApplicationUser : IdentityUser'
.Property(b => b.ConcurrencyStamp)
.IsETagConcurrency();
}
I have made a blazor project that is hooked up to a database that pulls information via a form. I have also gone ahead and added a migration for this DB. Now our production database has new tables being made every 90 days. My question is for EF Core is there something I can write in the code that would update my solution with the newest Db changes and runs once a day? I have read up on EF Core scripts but could not find any concrete examples. Any advice would be grealy appreciated.
Assuming it is a Blazor Server app, in your Program.cs you can migrate your database every time the application starts (if there are new migrations) by doing something like this:
var host = CreateHostBuilder(args).Build();
using var scope = host.Services.CreateScope();
var services = scope.ServiceProvider;
var context = services.GetRequiredService<YourDbContext>();
await context.Database.Migrate(); // or MigrateAsync();
host.Run();
I am using ef core in project and my repository calls a stored procedure to get the results. I was wondering if I can use inMemorydatabase feature of ef core to test against my repository.
You can but you should not do it. From Microsoft:
EF Core comes with an in-memory database that we use for internal
testing of EF Core itself. This database is in general not suitable
for testing applications that use EF Core. Specifically:
It is not a relational database.
It doesn't support transactions.
It cannot run raw SQL queries.
It is not optimized for performance.
None of this is very important when testing EF Core internals because
we use it specifically where the database is irrelevant to the test.
On the other hand, these things tend to be very important when testing
an application that uses EF Core.
https://learn.microsoft.com/en-us/ef/core/testing/#approach-3-the-ef-core-in-memory-database
Microsoft recommends using SQLite in-memory database instead. Always remember its lifetime though:
The database is created when the connection to it is opened
The database is deleted when the connection to it is closed
Sample:
public class SqliteInMemoryItemsControllerTest : ItemsControllerTest, IDisposable
{
private readonly DbConnection _connection;
public SqliteInMemoryItemsControllerTest()
: base(
new DbContextOptionsBuilder<ItemsContext>()
.UseSqlite(CreateInMemoryDatabase())
.Options)
{
_connection = RelationalOptionsExtension.Extract(ContextOptions).Connection;
}
private static DbConnection CreateInMemoryDatabase()
{
var connection = new SqliteConnection("Filename=:memory:");
connection.Open();
return connection;
}
public void Dispose() => _connection.Dispose();
}
https://learn.microsoft.com/en-us/ef/core/testing/sqlite#using-sqlite-in-memory-databases
I have a WebApi setup and due to some reasons, I am facing performace issues with some of the api methods.
I would like to use MiniProfiler and to test the performance of these API methods and log the statistics delivered by Miniprofiler in to a Table.
The miniprofiler docs asks to add the follwing code,
using StackExchange.Profiling.Data;
...
public static MyModel Get()
{
var conn = new EFProfiledDbConnection(GetConnection(), MiniProfiler.Current);
return ObjectContextUtils.CreateObjectContext<MyModel>(conn);
}
Can somebody help me where actually this needs to be added, how the table will be Created and configured?
N.B: I am using EF 5 with Object Context Database First approach(Not DbContext)
This problem is not readily reproducible in a simple example here but was wondering if anyone has any experience and tips, here is the issue:
using Entity Framework
have many points in application where (1) data is written to some entity table e.g. Customer, (2) data is written to history table
both of these actions use Entity Framework, HOWEVER, they use different contexts
these actions need to be both in one transaction: i.e. if one fails to write, the other should not write, etc.
I can wrap them with a TransactionScope,
like this:
using (TransactionScope txScope = new TransactionScope()) {
...
}
but this gives me:
Microsoft Distributed Transaction Coordinator (MSDTC) is disabled for
network transactions.
Our database admin has told me that MSDTC is disabled by choice and can not be installed.
Hence I am making changes trying to create my own EntityConnection with a MetadataWorkspace with the idea that each context will use the same EntityConnection. However, this is proving near impossible trying to get it to work, e.g. currently I continue to get the above error even though theoretically both contexts are using EntityConnection. It's difficult to understand where/why Entity Framework is requiring the MSDTC for example.
Has anyone gone down this road before, have experience or code examples to share?
Well, the problem is quite easy.
If you are using sql server 2008 you should not have that problem because you have promotable transaction, and as .NET knows that you are using the same persistence store (the database) it wont promote it to DTC and commit it as local. look into promotable transaction with sql server 2008.
As far as I know Oracle is working in its driver to support promotable transactions, but I do not know the state, MS oracle driver does not support it.
http://www.oracle.com/technology/tech/windows/odpnet/col/odp.net_11.1.0.7.20_twp.pdf
If you are using a driver that do not support promotable transactions it is impossible for .NET to use local transaction doing two connections. You should change your architecture or convince the database admin for installing MSDTC.
I had a similar problem with SQL 2008, Entity Framework.
I had two frameworks defined (EF1, and EF2) but using identical connection strings to a sql 2008 database.
I got the MSDTC error above, when using nested "usings" across both.
eg the code was like this:
using (TransactionScope dbContext = new TransactionScope())
{
using (EF1 context = new EF1())
{
// do some EF1 db call
using (EF2 context2 = new EF2())
{
// do some EF2 db call
}
}
dbContext.Complete();
}
It wasnt as simple as this, because it was split across several methods, but this was the basic structure of "usings".
The fix was to only open one using at a time. No MTDSC error, No need to open distributed transactions on db.
using (TransactionScope dbContext = new TransactionScope())
{
using (EF1 context = new EF1())
{
// do some EF1 db call
}
using (EF2 context2 = new EF2())
{
// do some EF2 db call
}
dbContext.Complete();
}
I think that what you need to do is to force your contexts to share single database connection. You will be able then to perform these two operations against two different contexts in single transaction. You can achieve this by passing one EntityConnection object to both of your context's constructors. Of course this approach will require you to pass this object to methods which update DB.
I have recently blogged about creating database context scope which will make using multiple EF contexts and transactions easier.