先谢谢你的帮助。
我试图和朋友一起制作一个小RPG的数据库。到目前为止,我们一直在跟踪JSON文件中的攻击类型等事情(我的朋友并不精通技术,因此我们只是在纯文本文件的早期就妥协了)。我想让他成为一个网站,以便他可以更轻松地编辑我们的想法(类型,怪物,可能的攻击等)之间的关系。
因此,我所提供的数据如下所示:
{
"name": "water",
"isElement": true,
"defendAgainst": [
"fire",
"undead",
"atomic",
"food"
],
"immuneTo": [
"water"
],
"weakTo": [
"electric",
"zoetic",
"sonic",
"eldritch"
]
}, ... and so on
在这个例子中,水是一种元素,它可以抵御火力类型,它对水攻击免疫,对声音攻击也很弱。
我制作了一个将JSON转换为Object的东西,最终得到了类似的东西:
public class monsterType
{
[Key]
public string name { get; set; }
public ICollection<monsterType> weakTo { get; set; }
public ICollection<monsterType> immuneTo { get; set; }
public ICollection<monsterType> defendAgainst { get; set; }
public bool isElement { get; set; }
}
我通过以下方式从JSON翻译:
// set up the types references
foreach (typeJSON ty in typeListFromFile){
monsterType realTypeReference = lookUpMonsterTypeFromJSONtype(ty, realTypes);
//convert those lists
ICollection<monsterType> mtWTs = ty.weakTo.Select(w => lookUpMonsterTypeFromName(w, realTypes)).ToList();
ICollection<monsterType> mtDAs = ty.defendAgainst.Select(w => lookUpMonsterTypeFromName(w, realTypes)).ToList();
ICollection<monsterType> mtITs = ty.immuneTo.Select(w => lookUpMonsterTypeFromName(w, realTypes)).ToList();
//set them on the real type reference
realTypeReference.weakTo = mtWTs;
realTypeReference.defendAgainst = mtDAs;
realTypeReference.immuneTo = mtITs;
}
数据进入monsterType的实例就好了。我和40个怪物类型坐在一起很漂亮,而且它们都很好地互相引用。
我正在使用这个项目来教自己MVC和实体框架(代码优先?),虽然我过去和Flask一样玩过,但我这里的水很少在C#.net的土地上,请原谅我,如果我错过了一些完全明显的东西。
我已经与SQL Server数据库建立了数据库连接,并且它正在创建realTypes表OK但是它缺少免费提交,弱访问和保护反对列I&amp; #39; d期待,我认为这是因为这都是自我指涉的。
好吧,我做了一个数据上下文:
public class monsterDataContext : DbContext
{
public monsterDataContext() : base("name=blood")
{
}
public DbSet<monsterType> Types { get; set; }
}
我只是遍历我的列表并保存我的更改:
using (var theDB = new monsterDataContext())
{
foreach (monsterType ty in realTypes)
{
theDB.Types.Add(ty);
}
theDB.SaveChanges();
}
当我这样做时,它在DB.SaveChanges()上的错误:
违反了多重性约束。角色 &#39; monsterType_defendAgainst_Source&#39;关系 &#39; ParseMonsterYaml.monsterType_defendAgainst&#39;具有多重性1或 0..1。
我不确定为什么会出现这个问题?
它还创建了一个很棒的桌子,但这些列并没有真正符合我的期望:
name, isElement, monsterType_name, monsterType_name1, monsterType_name2
但这并不像错误那么重要。没有数据被加载到表中,它是空的。
我做错了什么?有什么根本的吗?我遇到了可怕的事吗?还有更好的方法吗?
答案 0 :(得分:1)
当您需要自定义列名称时,您必须告诉EF它们的名称,您可以执行以下操作。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<MonsterType>()
.HasRequired(t => t.DefendAgainst)
.WithMany()
.Map(configuration => configuration.MapKey("DefendAgainst"));
modelBuilder.Entity<MonsterType>()
.HasRequired(t => t.ImmuneTo)
.WithMany()
.Map(configuration => configuration.MapKey("ImmuneTo"));
modelBuilder.Entity<MonsterType>()
.HasRequired(t => t.WeakTo)
.WithMany()
.Map(configuration => configuration.MapKey("WeakTo"));
base.OnModelCreating(modelBuilder);
}
关于您的错误,默认情况下,您的一对多关系列创建为NOT NULL,这就是为什么当您使用缺少的数据进行保存时,它会违反SQL约束。如果DefendAgaint,WeekTo和ImmuneTo可以为null,那么在上面的代码中用.HasOptional替换.HasRequired,如下所示
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<MonsterType>()
.HasOptional(t => t.DefendAgainst)
.WithMany()
.Map(configuration => configuration.MapKey("DefendAgainst"));
modelBuilder.Entity<MonsterType>()
.HasOptional(t => t.ImmuneTo)
.WithMany()
.Map(configuration => configuration.MapKey("ImmuneTo"));
modelBuilder.Entity<MonsterType>()
.HasOptional(t => t.WeakTo)
.WithMany()
.Map(configuration => configuration.MapKey("WeakTo"));
base.OnModelCreating(modelBuilder);
}
这会生成此SQL
create table [dbo].[MonsterTypes] (
[Name] [nvarchar](128) not null,
[IsElement] [bit] not null,
[DefendAgainst] [nvarchar](128) null,
[ImmuneTo] [nvarchar](128) null,
[WeakTo] [nvarchar](128) null,
primary key ([Name])
);
alter table [dbo].[MonsterTypes] add constraint [MonsterType_DefendAgainst] foreign key ([DefendAgainst]) references [dbo].[MonsterTypes]([Name]);
alter table [dbo].[MonsterTypes] add constraint [MonsterType_ImmuneTo] foreign key ([ImmuneTo]) references [dbo].[MonsterTypes]([Name]);
alter table [dbo].[MonsterTypes] add constraint [MonsterType_WeakTo] foreign key ([WeakTo]) references [dbo].[MonsterTypes]([Name]);
希望我明白这一点!