I wish to run a raw SQL Delete Query on EF Core and I am suing the following guide to help me along:
https://learn.microsoft.com/en-us/ef/ef6/querying/raw-sql
The code:
using (accountingContext db = new())
{
db.Database.ExecuteSqlCommand("DELETE FROM ...");
}
but I get the error:
DatabaseFacade does not contain a definition for 'ExecuteSqlCommand'
my accountingContext class:
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
namespace WebApi.Models
{
public partial class accountingContext : DbContext
{
public DbSet<User>? Users { get; set; }
public DbSet<Transaction>? Transactions { get; set; }
public DbSet<TransactionStaging>? TransactionsStaging { get; set; }
public accountingContext()
{
}
public accountingContext(DbContextOptions<accountingContext> options) : base(options)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer("****");
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
}
}
}
the .csproj file:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CsvHelper" Version="28.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.6">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.15.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Resources\Temp\" />
</ItemGroup>
</Project>
What am I doing wrong here?
The following resolved the issue for me:
db.Database.ExecuteSqlRaw("...");
Not sure why all the docs I was going through were suggesting the use of ExecuteSqlCommand but eventually I stumbled on the correct command.
You need to add the following packages to be able to use the EF 6.0:
Don't use any other EntityFramework packages. Also, your solution should be for .Net 6.0.
Related
I'm trying to add diagnostic output to my xUnit tests. For this, I'm using a combination of Collection Fixture and IMessageSink. This is my code:
using System;
using Xunit;
using Xunit.Abstractions;
using Xunit.Sdk;
namespace MessageSink
{
[Collection("My collection")]
public class UnitTest1
{
private readonly MyCollectionFixture _fixture;
public UnitTest1(MyCollectionFixture fixture)
{
_fixture = fixture;
}
[Fact]
public void Test1()
{
_fixture.Sink.OnMessage(new DiagnosticMessage("Hello World"));
}
}
public class MyCollectionFixture : IDisposable
{
public MyCollectionFixture(IMessageSink sink)
{
Sink = sink;
}
public IMessageSink Sink { get; }
public void Dispose()
{
}
}
[CollectionDefinition("My collection")]
public class MyCollection : ICollectionFixture<MyCollectionFixture>
{
}
}
Within the test project, I've created the following xunit.runner.json:
{
"$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
"diagnosticMessages": true
}
And this is my project configuration:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.0.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Content Include="xunit.runner.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
I'd expect Hello World within the output of the test runner - but it is empty.
I (hopefully 🤞🏻) followed the docs in the correct way:
Shared Context between Tests
Capturing Output
Configuration Files
What am I doing wrong?
Thanks and cheers 👋🏻
You'll need to extend IClassFixture<MyCollectionFixture> to get that working for diagnostic messages.
For in-test messages, try using ITestOutputHelper which you can pass in into your test class along with MyCollectionFixture.
Check docs out: https://xunit.net/docs/capturing-output
I'm trying to build a ASP.NET Core WebApi with Entity Framework Core and AutoMapper. When i try to use Add-Migration i get Exception has been thrown by the target of an invocation. at Microsoft.EntityFrameworkCore.Tools.Program.Main(String[] args)(I haven't made any changes to the Program class). I think the problem may be that the program cannot find the connection string.
This is my DataBaseContext Class:
public class DataBaseContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
.AddJsonFile("appsettings.json")
.Build();
optionsBuilder.UseSqlServer(configuration.GetConnectionString("DataBaseContext"));
}
public DataBaseContext(DbContextOptions<DataBaseContext> options) : base(options)
{
}
public DbSet<Director> Directors { get; set; }
public DbSet<Movie> Movies { get; set; }
}
This is appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"DataBaseContext": "Server=DESKTOP-LLPVCRN\\KISIELSQL;Database=KredekMovieManagement;Trusted_Connection=True;MultipleActiveResultSets=true"
}
}
This is Startup.cs:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DataBaseContext>(opt =>
opt.UseSqlServer("DataBaseContext"));
var config = new AutoMapper.MapperConfiguration(c =>
{
c.AddProfile(new MapperProfile());
});
var mapper = config.CreateMapper();
services.AddSingleton(mapper);
services.AddSingleton<IUserService, UserService>();
services.AddControllers();
}
//some code
}
}
This is someproject.csproj:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="10.1.1" />
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="5.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="5.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.11">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.4" />
</ItemGroup>
</Project>
Because your project is a 3.1 version,your packages
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="5.0.2" />
are not compatible.
You need change it to:
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.11" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.1.11" />
adding nlog to .net core 3.0 application results in
'IServiceCollection' does not contain a definition for
'ConfigureLoggerService' and no accessible extension method
'ConfigureLoggerService' accepting a first argument of type
'IServiceCollection' could be found (are you missing a using directive
or an assembly reference?)
for Nuget I have
NLog.Extensions.Logging v1.6.1
NLog.Web.AspNetCore v4.9.0
in startup.cs
public Startup(IConfiguration config)
{
LogManager.LoadConfiguration(String.Concat(Directory.GetCurrentDirectory(), "/nlog.config"));
Configuration = config;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(IISDefaults.AuthenticationScheme);
services.AddMvc();
services.AddTransient<ICwopaAgencyFileRepository, CwopaAgencyFileRepository>();
services.AddTransient<ICurrentUserRepository, CurrentUserRepository>();
services.AddTransient<IUserRepository, UserRepository>();
services.AddTransient<IRevenueReceivedRepository, RevenueReceivedRepository>();
services.AddTransient<ILesseeRepository, LesseeRepository>();
services.AddTransient<ITractLesseeJunctionRepository, TractLesseeJunctionRepository>();
services.AddTransient<IPadRepository, PadRepository>();
services.AddTransient<IWellRepository, WellRepository>();
services.AddTransient<IWellOperarationRepository, WellOperationRepository>();
services.AddTransient<IRoyaltyRepository, RoyaltyRepository>();
services.AddTransient<IRoyaltyAdjustmentCardViewModelRepository, RoyaltyAdjustmentCardViewModelRepository>();
services.AddSingleton<ILoggerManager, LoggerService>();
string conString = Configuration["ConnectionStrings:DefaultConnection"];
services.AddDbContext<DataContext>(options =>
options.UseSqlServer(conString));
services.ConfigureLoggerService();
services.AddMvc(option => option.EnableEndpointRouting = false);
services.AddMemoryCache();
services.AddSession();
}
here is my csproj file
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup Label="Globals">
<SccProjectName>SAK</SccProjectName>
<SccProvider>SAK</SccProvider>
<SccAuxPath>SAK</SccAuxPath>
<SccLocalPath>SAK</SccLocalPath>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.0.0" />
<PackageReference Include="NLog" Version="4.6.8" />
<PackageReference Include="NLog.Extensions.Logging" Version="1.6.1" />
<PackageReference Include="NLog.Web.AspNetCore" Version="4.9.0" />
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Migrations\" />
</ItemGroup>
</Project>
if you're following this tutorial, don't forget add this method extension
public static void ConfigureLoggerService(this IServiceCollection services)
{
services.AddSingleton<ILoggerManager, LoggerManager>();
}
because you're calling it in this line
services.ConfigureLoggerService();
Also, you can considere removing it, because you're registering this service LoggerService with the interface ILoggerManager.
Here are my steps:
1. Create a static class called ExceptionMiddlewareExtensions
2. Within ExceptionMiddlewareExtensions create a static function called ConfigureExpectionHandler.
3. In the start.cs - public void Configure - add the ILogger interface
4. In the start.cs, setup the dependency injection for ILogger, in ConfigureServices(IServiceCollection services). Create a serviceProvider then GetService based on ILogger<MyClassName>>(). Create a service singleton(type(ILogger),logger)
5. In the controller code, throw new Exception with message upon error condition
Create an Extension directory with the following class
public static class ExceptionMiddlewareExtensions
{
//public static void ConfigureExceptionHandler(this IApplicationBuilder app, ILoggerManager logger)
public static void ConfigureExceptionHandler(this IApplicationBuilder app, ILogger logger)
{
app.UseExceptionHandler(appError =>
{
appError.Run(async context =>
{
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
context.Response.ContentType = "application/json";
var contextFeature = context.Features.Get<IExceptionHandlerFeature>();
if (contextFeature != null)
{
logger.LogError($"Something went wrong: {contextFeature.Error}");
await context.Response.WriteAsync(new ErrorDetails()
{
StatusCode = context.Response.StatusCode,
Message = String.Format("Error: {0}", contextFeature.Error.Message)
}.ToString());
}
});
});
}
}
In Startup.cs added the following line
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILogger logger)
{
app.ConfigureExceptionHandler(logger);
}
In startup.cs add the following singleton
public void ConfigureServices(IServiceCollection services)
{
var serviceProvider = services.BuildServiceProvider();
var logger = serviceProvider.GetService<ILogger<ApplicationLogs>>();
services.AddSingleton(typeof(ILogger), logger);
}
in logs directory add the following class
public class ApplicationLogs
{
}
In the controller throw the Exception
public async Task<IActionResult> AddLoginView([FromBody] LoginView param)
{
if (error_condition)
{
throw new Exception("The user error messages");
}
}
Adding migrations and updating database were working fine but seem to have hit a snag after updating to the latest version of Entity Framework core.
What am I missing?
Failing Command
add-migration authenticationtoken -Context ApplicationDbContext -verbose
ApplicationDbContext.cs
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
// I added this constructor after add-migration complained about
//needing a paramterless contructor.
public ApplicationDbContext()
{
}
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
...................
}
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options=> options.UseSqlServer(Configuration.GetConnectionString("SQLServerConnectionString")));
..............
}
Program.cs
public class Program
{
public static void Main(string[] args)
{
try
{
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseSerilog()
.Build()
.Run();
}
finally
{
Log.CloseAndFlush();
}
}
}
project.csproj:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<LangVersion>default</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Braintree" Version="4.11.0" />
<PackageReference Include="BuildBundlerMinifier" Version="2.9.406" />
<PackageReference Include="Hangfire" Version="1.7.3" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.Azure.Cosmos.Table" Version="1.0.1" />
<PackageReference Include="Microsoft.Azure.Storage.Blob" Version="10.0.3" />
<PackageReference Include="Microsoft.Azure.Storage.Common" Version="10.0.3" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.3" />
<PackageReference Include="morelinq" Version="3.1.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="Sendgrid" Version="9.11.0" />
<PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />
<PackageReference Include="Serilog.Extensions.Logging" Version="2.0.4" />
<PackageReference Include="Serilog.Settings.AppSettings" Version="2.2.2" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.0.1" />
<PackageReference Include="Serilog.Sinks.MSSqlServer" Version="5.1.2" />
<PackageReference Include="Stripe.net" Version="26.0.0" />
<PackageReference Include="Syncfusion.EJ2.AspNet.Core" Version="17.1.0.48" />
</ItemGroup>
</Project>
StackTrace:
System.InvalidOperationException: No database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.OnConfiguring method or by using AddDbContext on the application service provider. If AddDbContext is used, then also ensure that your DbContext type accepts a DbContextOptions<TContext> object in its constructor and passes it to the base constructor for DbContext.
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.Initialize(IServiceProvider scopedProvider, IDbContextOptions contextOptions, DbContext context)
at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
at Microsoft.EntityFrameworkCore.DbContext.Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure<System.IServiceProvider>.get_Instance()
at Microsoft.EntityFrameworkCore.Internal.InternalAccessorExtensions.GetService[TService](IInfrastructure`1 accessor)
at Microsoft.EntityFrameworkCore.Infrastructure.AccessorExtensions.GetService[TService](IInfrastructure`1 accessor)
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func`1 factory)
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType)
at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_1.<.ctor>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
No database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.OnConfiguring method or by using AddDbContext on the application service provider. If AddDbContext is used, then also ensure that your DbContext type accepts a DbContextOptions<TContext> object in its constructor and passes it to the base constructor for DbContext.
Thank you #ivanStoev for your link, I was able to fix the issue by adding a public static CreateWebHostBuilder method, (which I had mistakenly refactored).
Program.cs:
public class Program
{
public static void Main(string[] args)
{
try
{
var iWebHost = CreateWebHostBuilder(args).Build();
Log.Information("Application starting");
iWebHost.Run();
}
catch (Exception exception)
{
Log.Error(exception.ToString());
}
finally
{
Log.CloseAndFlush();
}
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseSerilog();
}
I am having trouble referencing the documented method AddResultFile() on the TestContext class, allegedly found in the Microsoft.VisualStudio.TestTools.UnitTesting package/namespace.
This is my package list:
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
<PackageReference Include="Selenium.Support" Version="3.141.0" />
<PackageReference Include="Selenium.WebDriver" Version="3.141.0" />
<PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="2.46.0" />
<PackageReference Include="specflow" Version="3.0.199" />
<PackageReference Include="SpecFlow.Tools.MsBuild.Generation" Version="3.0.199" />
<PackageReference Include="SpecFlow.MsTest" Version="3.0.199" />
<PackageReference Include="MSTest.TestFramework" Version="2.0.0-beta4" />
<PackageReference Include="MSTest.TestAdapter" Version="2.0.0-beta4" />
This is (a part of) my test (step definition - it's SpecFlow) class:
using System;
using System.IO;
using System.Text;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
using TechTalk.SpecFlow;
using XunitTestLib.Drivers;
using XunitTestLib.Helpers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace XunitTestLib.StepDefinitions
{
[Binding]
public class BrowserSteps : BrowserDriver
{
public IWebElement CurrentElement { get; set; }
public TestContext TestContext { get; set; }
public BrowserSteps(TestContext tcontext)
{
this.TestContext = tcontext;
}
[Given(#"I navigate to (.*)")]
[When(#"I navigate to (.*)")]
[Then(#"I navigate to (.*)")]
public void INavigateTo_(string url)
{
Browser.Navigate().GoToUrl(url);
}
// ***Numerous methods for specflow/selenium-based testing***
[Given(#"I take a screenshot")]
[When(#"I take a screenshot")]
[Then(#"I take a screenshot")]
public void ITakeAScreenshot()
{
var sep = Path.DirectorySeparatorChar;
var time = DateTime.Now.ToString("yyyy-MM-dd_HH_mm_SS_") + DateTime.Now.Ticks;
var path = $#"{Directory.GetCurrentDirectory()}{sep}{time}.png";
Browser
.GetScreenshot()
.SaveAsFile(path);
TestContext.AddResultFile(path); // THIS METHOD NOT FOUND
}
}
}
How do I find and use the AddResultFile() method? I assume I'm missing a reference...?
There was a bug in MSTest.TestFramework package reported here:
https://github.com/Microsoft/testfx/issues/394
It is resolved 4 days ago from today in a pull request :
https://github.com/Microsoft/testfx/pull/609
But I can not see any update in nuget version from last 23 days for version 2.0.0-beta4 and there is no version after that right now. https://www.nuget.org/packages/MSTest.TestFramework/
Intermediate fix is to use latest bits from here till there is new update with this fix:
https://dotnet.myget.org/F/mstestv2/api/v3/index.json
In particular, you should update your adapter and framework nuget package to these versions:
https://dotnet.myget.org/feed/mstestv2/package/nuget/MSTest.TestAdapter/2.0.0-build-20190430-01
https://dotnet.myget.org/feed/mstestv2/package/nuget/MSTest.TestFramework/2.0.0-build-20190430-01
Update 09/2019: the v2 of the MS Test Framework was officially released with the method in question included.