子类的唯一实体框架

时间:2018-01-17 20:06:51

标签: c# asp.net entity-framework entity-framework-core

我对如何在实体框架中处理这种情况感到困惑。

我有一个角色基类:

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都是名字独一无二的!如何仅在派生类中设置唯一?

1 个答案:

答案 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);

    };
?>