我正在玩智慧 EF Core 2.1 Preview 2 。
我在OnModelCreating(ModelBuilder modelBuilder)
我的模型是没有注释的简单POCO类。
public class Tenant {
public int TenantID {get; set;}
public string Name {get; set;}
}
我的DbContext
内OnModelCreating
方法中的是DB模型定义为
modelBuilder.Entity<Tenant>(e => {
e.HasKey(m => m.TenantID)
.HasName("PK_Tenants");
e.Property(m => m.TenantID)
.UseSqlServerIdentityColumn();
e.Property(m => m.Name)
.IsRequired()
.HasMaxLength(256);
}
并且种子方法定义为:
modelBuilder.Entity<Tenant>().HasData(new []{
new Tenant {
TenantID = 0,
Name = "SystemTenant",
}
});
在startap期间,当运行ctx.Database.Migrate()时,我得到了异常: 无法添加实体类型“租户”的种子实体,因为没有为所需属性'TenantID
提供值答案 0 :(得分:3)
这个例外有点误导。内部必须有一些机制,它测试所需的属性,因此它们必须与默认值不同。
我必须做的唯一改变是指定TenantID != 0
。
modelBuilder.Entity<Tenant>().HasData(new []{
new Tenant {
TenantID = 1, // Must be != 0
Name = "SystemTenant",
}
});
答案 1 :(得分:2)
在对EF Core代码进行反向工程并发现了this行代码之后,我创建了一些小的“ hack”来绕过0 PK值限制。 与@Tomino答案有关。 这是我的扩展代码:
using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
namespace EntityFrameworkCore.CustomMigration
{
public static class CustomModelBuilder
{
public static bool IsSignedInteger(this Type type)
=> type == typeof(int)
|| type == typeof(long)
|| type == typeof(short)
|| type == typeof(sbyte);
public static void Seed<T>(this ModelBuilder modelBuilder, IEnumerable<T> data) where T : class
{
var entnty = modelBuilder.Entity<T>();
var pk = entnty.Metadata
.GetProperties()
.FirstOrDefault(property =>
property.RequiresValueGenerator()
&& property.IsPrimaryKey()
&& property.ClrType.IsSignedInteger()
&& property.ClrType.IsDefaultValue(0)
);
if (pk != null)
{
entnty.Property(pk.Name).ValueGeneratedNever();
entnty.HasData(data);
entnty.Property(pk.Name).UseSqlServerIdentityColumn();
}
else
{
entnty.HasData(data);
}
}
}
}
您可以在OnModelCreating
方法中像这样使用它:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Seed(new List<Tenant> {
new Tenant() {TenantID = 0 , Name = string.Empty},
new Tenant() {TenantID = 1 , Name = "test"}
//....
);
//....
}
答案 2 :(得分:0)
我正在使用自定义服务将数据提取到数据库,我这样做是这样的:
C:\Program Files\JetBrains\IntelliJ IDEA xxxx.xx.xx\bin
我必须将其更改为private void _MakeMesh(int sides, float radius = 0.5f)
{
m_LiquidMesh.Clear();
float angleStep = 360.0f / (float) sides;
List<Vector3> vertexes = new List<Vector3>();
List<int> triangles = new List<int>();
List<Vector2> uvs = new List<Vector2>();
Quaternion rotation = Quaternion.Euler(0.0f, angleStep, 0.0f);
// Make first triangle.
vertexes.Add(new Vector3(0.0f, 0.0f, 0.0f));
vertexes.Add(new Vector3(radius, 0.0f, 0.0f));
vertexes.Add(rotation * vertexes[1]);
// First UV ??
uvs.Add(new Vector2(0, 0));
uvs.Add(new Vector2(1, 0));
uvs.Add(rotation * uvs[1]);
// Add triangle indices.
triangles.Add(0);
triangles.Add(1);
triangles.Add(2);
for (int i = 0; i < sides - 1; i++)
{
triangles.Add(0);
triangles.Add(vertexes.Count - 1);
triangles.Add(vertexes.Count);
// UV ??
vertexes.Add(rotation * vertexes[vertexes.Count - 1]);
}
m_LiquidMesh.vertices = vertexes.ToArray();
m_LiquidMesh.triangles = triangles.ToArray();
m_LiquidMesh.uv = uvs.ToArray();
m_LiquidMesh.RecalculateNormals();
m_LiquidMesh.RecalculateBounds();
Debug.Log("<color=yellow>Liquid mesh created</color>");
}
How does mapping UV work in a case like this?
:
builder.Entity<EntityName>().HasData(someSerive.GetById(id).AsEnumerable());
答案 3 :(得分:0)
我在我的一个存储库中收到此错误。
Exception has occurred: CLR/System.InvalidOperationException
Exception thrown: 'System.InvalidOperationException' in Microsoft.EntityFrameworkCore.dll:
'The seed entity for entity type 'SubscriptionType'
cannot be added because a default value was provided for the required property 'Id'.
Please provide a value different from '00000000-0000-0000-0000-000000000000'.'
at Microsoft.EntityFrameworkCore.Infrastructure.ModelValidator.ValidateData(IModel model, IDiagnosticsLogger`1 logger)
at Microsoft.EntityFrameworkCore.Infrastructure.ModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger)
at Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger)
at Microsoft.EntityFrameworkCore.SqlServer.Internal.SqlServerModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger)
问题是我使用 new Guid()
将值分配给 id
字段,这只是一个错误。 new Guid
将只创建全零的虚拟 Guid,而 Guid.NewGuid()
将创建唯一的 Guid。所以,我不得不在我的代码中使用 Guid.NewGuid()
。
builder.Entity<SubscriptionType>(b =>
{
b.HasKey(k => k.Id);
b.HasData(new SubscriptionType { Id = Guid.NewGuid(), Name = "SeatBased" },
new SubscriptionType { Id = Guid.NewGuid(), Name = "NonSeatBased" },
new SubscriptionType { Id = Guid.NewGuid(), Name = "AzureEntitlement" },
new SubscriptionType { Id = Guid.NewGuid(), Name = "Bundle" });
});