Strange schema naming with EF core code-first - sql-server

I'm having a weird issue that I've never seen before, with schema naming using EF core code-first.
I just created a new class LogEntry used to log SMS and emails sent to our users.
public class LogEntry
{
public LogEntry(Guid id)
{
Id = id;
}
public Guid Id { get; set; }
public Provider Provider { get; set; } // Enum
public string Content { get; set; }
public string Recipient { get; set; }
...
}
I then added configuration in my database context class, in OnModelCreating(modelBuilder modelBuilder)
public virtual DbSet<LogEntry> Log { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<LogEntry>(entity =>
{
entity.HasKey(log => log.Id);
entity.HasIndex(log => log.Date);
entity.HasIndex(log => log.Provider);
entity.HasIndex(log => log.Recipient);
...
});
}
Then I ran dotnet ef migrations add SomeMigration to actually add the migration. I setup auto migration so it automatically updates my database when the project launches. So far so good.
Now, once I went to check out the new tables it created, I made a weird naming convention regarding the databae schema.
My IIS website application pool is running with a specific managed AD user, let's call it msvc-log-api
I'm used to EF always using the dbo schema, as it default to that schema, but for some weird reason, EF decided to create a new schema named after my managed AD user mydomain\msvc-log-api$. This means that my tables are named in the following way:
mydomain\msvc-log-api$.__EFMigrationHistory
mydomain\msvc-log-api$.Log
Any idea why this is happening, and do I really need to add modelBuilder.HasDefaultSchema("dbo") to mitigate this issue?

Related

How to prevent EF Core Code First from scaffolding SQL Server Views

I know SQL Server views are supported in EF Core. Using the code first approach, EF Core 7 keeps scaffolding my SQL Server Views. I do not want it to. The only way I've been able to accomplish this it to use
modelBuilder.Ignore<LogBudgetView>();
I then have to comment that out after scaffolding because if I don't then EF Core won't recognize my view when I try to use it which is annoying. Any idea how I can get EF Core to STOP scaffolding my SQL Server Views?
My code...
public class LogBudgetView
{
public int Id { get; set; }
public string Message { get; set; } = null!;
...
public virtual DbSet<LogBudgetView> LogBudgetViews { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// views
modelBuilder.Entity<LogBudgetView>().ToView("vwBudgetLog").HasKey(x => x.Id);
//modelBuilder.Ignore<LogBudgetView>();
...

code first .net core publish has no database tables

I'm pretty new to both Azure and code first. I have an app which works locally. I published the web project using the visual studio wizard. All worked well.
However its missing all the db tables.
I had a look at the connection string which has a "DefaultConnection". Locally its "Server=(localdb)\...".
In azure it appears as "Data Source=tcp:Sniipedb.database.windows.net,1433"
I have a db initializer which seeds the data but it only works locally.
My AppDBContext I assume should have created the db.
The actual error on the site online is "SqlException: Invalid object name 'Users'.
System.Data.SqlClient.SqlConnection.OnError(SqlException exception, bool breakConnection, Action wrapCloseInAction)"
When I look in the DB, however, there are no tables.
I'm making a simple chores app. Users is a DB table.
To create users I have the following:
within startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AppDBContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddTransient<IUserRepository, UserRepository>();
services.AddTransient<ITaskRepository, TaskRepository>();
services.AddMvc();
}
within the AppDBContext : DbContext
public DbSet<User> Users {Get; set;}
User is a simple class
public class User
{
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[Key]
public string EMailAddress { get; set; }
public ICollection<UserTask> UserTasks { get; set; }
}
I have a DBInitializer which seeds new users and saves the context.
This works flawlessly on the local machine.
The solution for me was to configure my Publish. Within the settings it has a "databases" option where the "use this connection string at runtime" was unchecked.
Also under "Entity Framework Migrations" the "Apply this migration on publish" was unchecked.
By checking those two, then saving and then publishing it worked.

net core 1 (dnx 4.5.1) with enterpriselibrary 6 - setting up the connection string

i ve big problems running enterprise library data access block with net core 1 (dnx 4.5.1)
How can i setup the default connection string for entlib
my appsettings.json
"ConnectionString": "Server=localhost\sqlexpress;Initial Catalog=blind;User Id=blind;Password=blind"
Here is my problem (no default connectionstring)
Database db = DatabaseFactory.CreateDatabase();
how can i pass the appsettings ConnectionString to the entlib databasefactory
any help would be greatly appreciated
I know it's an old question, but I have a similar setup (but using .NET Core 2.0) and it took me awhile to figure out how to set the default database connection without using the web.config to manage it.
What I did was include the default database and all of the connection strings in the appsettings.json and then in my Startup class I read the appsettings.json into an object that I defined to store the default db name and the connection strings and configure the default + named database using DatabaseFactory.SetDatabase.
DatabaseFactory.SetDatabases() Definition
public class DataConfiguration
{
public string DefaultDatabase { get; set; }
public List<ConnectionStringSettings> ConnectionStrings { get; set; }
}
public class Startup
{
public Startup(IConfiguration configuration)
{
//Get the Database Connections from appsettings.json
DataConfig = configuration.Get<DataConfiguration>();
var defaultDb = DataConfig.ConnectionStrings?.Find(c => c.Name == DataConfig.DefaultDatabase);
DatabaseFactory.SetDatabases(() => new SqlDatabase(defaultDb.ConnectionString), GetDatabase);
Configuration = configuration;
}
public Database GetDatabase(string name)
{
var dbInfo = DataConfig.ConnectionStrings.Find(c => c.Name == name);
if (dbInfo.ProviderName == "System.Data.SqlClient")
{
return new SqlDatabase(dbInfo.ConnectionString);
}
return new MySqlDatabase(dbInfo.ConnectionString);
}
}
Whenever there is documentation, I always suggest reading it as it is usually good. This is one of those examples, check out the "Getting Started with ASP.NET 5 and Entity Framework 6". There are several things that you need to do to ensure that you are correctly configured.
Setup your connection string and DI.
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
}
Also, notice the path in the configuration, it seems to differ from yours.
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped((_) =>
new ApplicationDbContext(
Configuration["Data:DefaultConnection:ConnectionString"]));
// Configure remaining services
}

Why is Entity Framework ignoring my connection string?

I have a connection string:
<add name="Gini" providerName="System.Data.SqlClient" connectionString="user id=user;Password=pa55;Data Source=server;Database=gini" />
I want EF to be able to control the creation of the database and updates through migrations so I'm letting it have complete control over the DB.
My contact class looks like the following:
public class GiniContext : DbContext
{
public DbSet<UserSession> UserSessions { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new UserSessionConfiguration());
}
public GiniContext() : base("Gini")
{
Database.Create();
}
}
I would expect this to create a database called "gini" on the server called "server" using the username and password as above but it's creating it on the (LocalDB)\v11.0 instance.
What am I doing wrong?
If you have two projects like a Class Library for Objects and a Web Application referencing it. You ll need to add the connection from app.config to the web.config in your web application.

EntityFramework unit test example

I just solved my own question, but thought I'd might still be helpful for others to read so decided to post it anyway.
I am trying to get started with azure development and am currently at the stage of getting the database up and running. After a few hickups I achieved the following:
installed VS2012, MSSQLSERVER2012, Azure SDK .NET, EntityFramework 6.0.0 alpha and a bunch of other things
wrote my first entities (code first) and generated a database out of it.
The last thing I'd like to see before I pick up the next challenge is to actually add something to my newly created database first. I'd thought the easiest way would be writing a test in nunit.
Here's what I got so far...
The entity class User:
namespace Models.Users
{
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string EmailAddress { get; set; }
}
}
The entity class UsersDb:
using System.Data.Entity;
namespace Models.Users
{
public class UsersDb : DbContext
{
public DbSet<User> Users { get; set; }
}
}
Generated the database with the following PS commands:
enable-migrations -ProjectName Models -ContextTypeName Models.Users.UsersDb
add-migration -ProjectName Models Initial
update-database -ProjectName Models
Finally, I wrote the following unit test
using Models.Users;
using NUnit.Framework;
namespace Tests
{
[TestFixture]
public class DatabaseTests
{
[Test]
public void AddUserTest()
{
var users = new UsersDb();
var user = new User
{
Id = 1,
Name = "test",
EmailAddress = "test#gmail.com"
};
users.Users.Add(user);
users.SaveChanges();
}
}
}
That test runs, but throws an exception I can't figure out.
System.InvalidOperationException : The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' for the 'System.Data.SqlClient' ADO.NET provider could not be loaded. Make sure the provider assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.
Solution
What I had to do to solve this, is open NuGet management (right click solution) and press the manage button on EntityFramework. In the dialog add a checkbox in front of your test solution, rebuild and go.
Now, I have a very small solution that creates a new user via a unit test and saves it into my database. A nice startup project which I can now start extending.
Solved the question while typing the question itself. Thought i'd still be useful as a reference for others.

Resources