我对如何在实体框架中处理这种情况感到困惑。
我有一个角色基类:
public class Character
{
[Key]
public Guid Id { get; set; }
public Realm Realm { get; set; }
public Guid RealmId { get; set; }
public string Name { get; set; }
}
角色有名字并且与领域绑定。
玩家控制的角色绝对是一个角色。它与玩家/用户绑定:
public class PlayerCharacter : Character
{
public User User { get; set; }
public Guid UserId { get; set; }
}
NPC也是一个角色:它不需要MCVE
的任何属性public class Npc : Character { }
现在,很明显,您不希望同一领域中的字符具有相同的名称,但您可以在单个领域中拥有尽可能多的Orcs
,因此我们需要定义唯一对PlayerCharacter
的约束,例如通过.HasAlternateKey
:
public DbSet<PlayerCharacter> Characters { get; set; }
public DbSet<Npc> Npcs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<PlayerCharacter>()
.HasAlternateKey("Name", "RealmId");
}
现在我们添加迁移:
$ dotnet ef migrations add 5
System.InvalidOperationException: A key cannot be configured on
'PlayerCharacter' because it is a derived type. The key must be
configured on the root type 'Character'.
好的,一个独特的索引怎么样?
modelBuilder.Entity<PlayerCharacter>()
.HasIndex("Name", "RealmId")
.IsUnique();
$ dotnet ef migrations add 5
Done. To undo this action, use 'ef migrations remove'
有效!但是等等:
migrationBuilder.CreateTable(
name: "Character",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
Discriminator = table.Column<string>(nullable: false),
Name = table.Column<string>(nullable: true),
RealmId = table.Column<Guid>(nullable: false),
// other props...
},
constraints: table =>
{
table.PrimaryKey("PK_Character", x => x.Id);
// foreign keys...
});
migrationBuilder.CreateIndex(
name: "IX_Character_Name_RealmId",
table: "Character",
columns: new[] { "Name", "RealmId" },
unique: true);
现在玩家角色和npcs都是名字独一无二的!如何仅在派生类中设置唯一?
答案 0 :(得分:5)
目前唯一可以做到的方法(EF Core 2.0.1)是使用基于Discriminator column值的过滤唯一索引。
不幸的是,HasFilter
流畅的API不是db不可知的。以下是SqlServer的配置:
<?php
$url = "example.com:80";
function curl($url) {
$handle = curl_init($url);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($handle, CURLOPT_HEADER, true);
curl_setopt($handle, CURLOPT_NOBODY, true);
curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($handle, CURLOPT_URL, $url);
$response = curl_exec($handle);
$httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
if($httpCode >= 200 && $httpCode < 400 || $httpCode == 401 || $httpCode == 405) {
echo "CURL GOOD, $httpCode";
echo "STATUS: GREEN";
}
else {
$fp = stream_socket_client("$url", $errno, $errstr);
if (!$fp) {
echo "CURL BAD, PING DOWN";
echo "STATUS: RED";
}
else {
echo "CURL BAD PING UP";
echo "STATUS: YELLOW";
}
}
curl_close($handle);
};
?>