Hey i have a question,
i tried to migrate to a database with
Microsoft.EntityFrameworkCore.SqlServer 3.0.0-preview6.19304.10
Microsoft.EntityFrameworkCore.Tools 3.0.0-preview6.19304.10
.NET Core 3.0 SDK 3.0.100-preview6-012264
i used
PM> add-migration
PM> update-database
Migration was okay but when i try to open it through /api/pizzas/getpizzas i got this problem:
System.ArgumentException: Expression must be writeable
Parameter name: left
at System.Linq.Expressions.Expression.RequiresCanWrite(Expression expression, String paramName)
at System.Linq.Expressions.Expression.Assign(Expression left, Expression right)
at System.Linq.Expressions.Expression.MakeBinary(ExpressionType binaryType, Expression left, Expression right, Boolean liftToNull, MethodInfo method, LambdaExpression conversion)
at System.Linq.Expressions.BinaryExpression.Update(Expression left, LambdaExpression conversion, Expression right)
at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
at Microsoft.EntityFrameworkCore.Relational.Query.Pipeline.RelationalShapedQueryCompilingExpressionVisitor.RelationalProjectionBindingRemovingExpressionVisitor.VisitBinary(BinaryExpression binaryExpression)
at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Dynamic.Utils.ExpressionVisitorUtils.VisitBlockExpressions(ExpressionVisitor visitor, BlockExpression block)
at System.Linq.Expressions.ExpressionVisitor.VisitBlock(BlockExpression node)
at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.VisitConditional(ConditionalExpression node)
at System.Linq.Expressions.ConditionalExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.VisitConditional(ConditionalExpression node)
at System.Linq.Expressions.ConditionalExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Dynamic.Utils.ExpressionVisitorUtils.VisitBlockExpressions(ExpressionVisitor visitor, BlockExpression block)
at System.Linq.Expressions.ExpressionVisitor.VisitBlock(BlockExpression node)
at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
at Microsoft.EntityFrameworkCore.Relational.Query.Pipeline.RelationalShapedQueryCompilingExpressionVisitor.RelationalProjectionBindingRemovingExpressionVisitor.VisitBinary(BinaryExpression binaryExpression)
at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Dynamic.Utils.ExpressionVisitorUtils.VisitBlockExpressions(ExpressionVisitor visitor, BlockExpression block)
at System.Linq.Expressions.ExpressionVisitor.VisitBlock(BlockExpression node)
at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Dynamic.Utils.ExpressionVisitorUtils.VisitBlockExpressions(ExpressionVisitor visitor, BlockExpression block)
at System.Linq.Expressions.ExpressionVisitor.VisitBlock(BlockExpression node)
at System.Linq.Expressions.BlockExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.Relational.Query.Pipeline.RelationalShapedQueryCompilingExpressionVisitor.VisitShapedQueryExpression(ShapedQueryExpression shapedQueryExpression)
at Microsoft.EntityFrameworkCore.Query.Pipeline.ShapedQueryCompilingExpressionVisitor.VisitExtension(Expression extensionExpression)
at System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.Query.Pipeline.QueryCompilationContext2.CreateQueryExecutor[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery2[TResult](Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass9_0`1.<Execute>b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetEnumerator()
at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.System.Collections.IEnumerable.GetEnumerator()
at System.Text.Json.Serialization.JsonSerializer.HandleEnumerable(JsonClassInfo elementClassInfo, JsonSerializerOptions options, Utf8JsonWriter writer, WriteStack& state)
at System.Text.Json.Serialization.JsonSerializer.Write(Utf8JsonWriter writer, Int32 flushThreshold, JsonSerializerOptions options, WriteStack& state)
at System.Text.Json.Serialization.JsonSerializer.WriteAsyncCore(Object value, Type type, Stream utf8Json, JsonSerializerOptions options, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonOutputFormatter.WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|29_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Using
Microsoft.EntityFrameworkCore.SqlServer 3.0.0-preview6.19304.10
Microsoft.EntityFrameworkCore.Tools 3.0.0-preview6.19304.10
.NET Core 3.0 SDK 3.0.100-preview6-012264
Run this code:
Pizza.cs
using System;
namespace blazor
{
public enum Spiciness
{
None,
Spicy,
Hot
}
public class Pizza
{
public Pizza() { }
public Pizza(int id, string name, decimal price,
Spiciness spiciness)
{
this.Id = id;
this.Name = name ?? throw new ArgumentNullException(nameof(name), "A pizza needs a name!");
this.Price = price;
this.Spiciness = spiciness;
}
public int Id { get; }
public string Name { get; }
public decimal Price { get; }
public Spiciness Spiciness { get; }
}
}
PizzaController.cs
using System.Linq;
using Microsoft.AspNetCore.Mvc;
namespace blazor
{
[Route("api/[controller]")]
[ApiController]
public class PizzasController : ControllerBase
{
private PizzaPlaceDbContext db;
public PizzasController(PizzaPlaceDbContext db)
{
this.db = db;
}
[HttpGet("pizzas")]
public IQueryable<Pizza> GetPizzas()
{
return db.Pizzas;
}
[HttpPost("pizzas")]
public IActionResult InsertPizza([FromBody] Pizza pizza)
{
db.Pizzas.Add(pizza);
db.SaveChanges();
return Created($"pizzas/{pizza.Id}", pizza);
}
}
}
PizzaDbContext.cs
using Microsoft.EntityFrameworkCore;
using blazor.Data;
namespace blazor
{
public class PizzaPlaceDbContext : DbContext
{
public PizzaPlaceDbContext(
DbContextOptions<PizzaPlaceDbContext> options)
: base(options)
{ }
public DbSet<Pizza> Pizzas { get; set; }
protected override void OnModelCreating(
ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
var pizzaEntity = modelBuilder.Entity<Pizza>();
pizzaEntity.HasKey(pizza => pizza.Id);
pizzaEntity.Property(pizza => pizza.Price)
.HasColumnType("money");
pizzaEntity.Property(pizza => pizza.Name);
pizzaEntity.Property(pizza => pizza.Spiciness);
}
}
}
Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using blazor.Data;
namespace blazor
{
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.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddSingleton<WeatherForecastService>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
}
}
Migration
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
namespace blazor.Migrations
{
public partial class pizza : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Pizzas",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
Name = table.Column<string>(nullable: true),
Price = table.Column<decimal>(type: "money", nullable: false),
Spiciness = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Pizzas", x => x.Id);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Pizzas");
}
}
}
Just json of pizzas
@netyam This is an issue with read-only fields. As a workaround, define the fields explicitly and make them not read-only. For example:
```C#
private int _id;
public int Id => _id;
For triage: more minimal repro:
```C#
public class Pizza
{
public Pizza() { }
public Pizza(int id, string name, decimal price)
{
Id = id;
Name = name ?? throw new ArgumentNullException(nameof(name), "A pizza needs a name!");
Price = price;
}
public int Id { get; }
public string Name { get; }
public decimal Price { get; }
}
public class PizzaPlaceDbContext : DbContext
{
public DbSet<Pizza> Pizzas { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var pizzaEntity = modelBuilder.Entity<Pizza>();
pizzaEntity.HasKey(pizza => pizza.Id);
pizzaEntity.Property(pizza => pizza.Price).HasColumnType("money");
pizzaEntity.Property(pizza => pizza.Name);
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Test;ConnectRetryCount=0");
}
public class Program
{
public static void Main()
{
using (var context = new PizzaPlaceDbContext())
{
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
context.Add(new Pizza(0, "Cheese", 1.0m));
context.SaveChanges();
}
using (var context = new PizzaPlaceDbContext())
{
foreach (var pizza in context.Pizzas)
{
Console.WriteLine(pizza.Name);
}
}
}
}
@netyam My book "Blazor Revealed" mentions that you should make the properties read-write now :) Actually funny that I encounter this here (since I am experimenting with the latest EF Core).
Greetings from Belgium!
Fixed in #15995
Regression test Query_and_update_using_constructors_with_property_parameters