Как установить составной первичный ключ для принадлежащих типов сущностей с использованием ядра 3.1.1 Entity Framework?

Я использую asp.net core 3.1 с efcore 3.1.1 и Microsoft.EntityFrameworkCore.Cosmos 3.1.1 для разработки API-интерфейсов graphql.

Вот детали моего кода:

Articles.cs

public class Articles
{
    public string id { get; set; }

    public int ArticleId { get; set; }

    public string PublishedDate { get; set; }

    public ICollection<RelatedArticlesSchema> RelatedArticles { get; set; }

    public ICollection<RelatedEntityId> RelatedCountries { get; set; }
}

RelatedArticlesSchema.cs

public class RelatedArticlesSchema
{
    [JsonProperty("ArticleId")]
    public int ArticleId { get; set; }

    [JsonProperty("Title")]
    public string Title { get; set; }

    public ICollection<RelatedEntityId> RelatedCountries { get; set; }

    [JsonProperty("PartitionKey")]
    public string PublishedDate { get; set; }
}

RelatedEntityId.cs

public class RelatedEntityId
{
    public int IdVal { get; set; }
}

SampleDbContext.cs

public class SampleDbContext : DbContext
{
    public DbSet<Articles> Articles { get; set; }

    public DbSet<Countries> Countries { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        var converter = new NumberToStringConverter<int>();
        modelBuilder.Entity<Articles>().Property(e => e.LanguageId).HasConversion(converter);
        modelBuilder.Entity<Articles>().HasPartitionKey(o => o.LanguageId);
        modelBuilder.Entity<Articles>().OwnsMany(p => p.RelatedCountries, a =>
        {
            a.WithOwner().HasForeignKey("Articlesid");
            a.Property<int>("id");
            a.Property(o => o.IdVal);
        }

        ).OwnsMany(p => p.RelatedArticles, a =>
        {
            a.OwnsMany(p => p.RelatedCountries, a =>
            {
                a.WithOwner().HasForeignKey("RelatedArticlesSchemaArticlesidid");
                a.Property<int>("id");
                a.Property(o => o.IdVal);
            }

            );
            a.WithOwner().HasForeignKey("Articlesid");
            a.Property<int>("id");
            a.Property(o => o.ArticleId);
            a.Property(o => o.Title);
            a.Property(o => o.PublishedDate);
        }

        ).OwnsMany(p => p.RelatedResources, a =>
        {
            a.OwnsMany(p => p.RelatedCountries, a =>
            {
                a.WithOwner().HasForeignKey("RelatedArticlesSchemaArticlesidid");
                a.Property<int>("id");
                a.Property(o => o.IdVal);
            }

            );
            a.WithOwner().HasForeignKey("Articlesid");
            a.Property<int>("id");
            a.Property(o => o.ArticleId);
            a.Property(o => o.Title);
            a.Property(o => o.PublishedDate);
        }

        );
    }
}

Вот данные в CosmosDB для коллекции: Статьи

{
  "ArticleId": 100,
  "PublishedDate": "12/1/2020 2:43:00 AM",
  "Author": null,
  "LanguageId": 37,
  "RelatedCountries": [
    {
      "IdVal": 1
    }
  ],
  "RelatedArticles": [
    {
      "ArticleId": 101,
      "Title": "Article_101",
      "RelatedCountries": [
        {
          "IdVal": 1
        }
      ],
      "PublishedDate": "5/26/2020 5:55:00 AM"
    },
    {
      "ArticleId": 102,
      "Title": "Article_102",
      "RelatedCountries": [
        {
          "IdVal": 1
        },
        {
          "IdVal": 2
        }
      ],
      "PublishedDate": "8/12/2020 4:57:00 AM"
    },
    {
      "ArticleId": 103,
      "Title": "Article_103",
      "RelatedCountries": [
        {
          "IdVal": 1
        },
        {
          "IdVal": 2
        },
        {
          "IdVal": 3
        }
      ],
      "PublishedDate": "8/20/2020 6:30:00 AM"
    },
    {
      "ArticleId": 104,
      "Title": "Article_104",
      "RelatedCountries": [
        {
          "IdVal": 10
        }
      ],
      "PublishedDate": "9/17/2020 6:06:00 AM"
    },
    {
      "ArticleId": 105,
      "Title": "Article_105",
      "RelatedCountries": [
        {
          "IdVal": 11
        }
      ],
      "PublishedDate": "11/26/2020 1:02:00 AM"
    }
  ]
}

Я получаю указанную ниже ошибку:

Свойство «RelatedArticlesSchemaArticlesidid» нельзя добавить к типу «RelatedArticlesSchema.RelatedCountries # RelatedEntityId», поскольку не указан тип свойства и отсутствует соответствующее свойство или поле среды CLR. Чтобы добавить свойство теневого состояния, необходимо указать тип свойства.

Может ли кто-нибудь помочь мне узнать, как решить эту проблему


person santosh kumar patro    schedule 04.03.2020    source источник
comment
Как говорится в ошибке, ни в одном из этих классов нет свойства RelatedArticlesSchemaArticlesidid. Вы должны настраивать каждую сущность отдельно в OnModelCreating, а не пытаться настраивать одну внутри другой. Даже если синтаксис предполагает, что вы можете вкладывать и вкладывать конфигурацию, это не работает.   -  person Panagiotis Kanavos    schedule 04.03.2020
comment
Я использовал статью для справки: docs.microsoft.com/en -us / ef / core / моделирования / принадлежащие-сущности   -  person santosh kumar patro    schedule 04.03.2020


Ответы (2)


Вам необходимо обновить свой класс dbcontext следующим образом:

        modelBuilder.Entity<Articles>().OwnsMany(p => p.RelatedCountries);
        modelBuilder.Entity<Articles>().OwnsMany(p => p.RelatedContacts);
        modelBuilder.Entity<Articles>().OwnsMany(p => p.RelatedCountryGroups);
        modelBuilder.Entity<Articles>().OwnsMany(p => p.RelatedTaxTags);
        modelBuilder.Entity<Articles>().OwnsMany(p => p.RelatedArticles, a =>
        {
            a.ToJsonProperty("RelatedArticles");
            a.OwnsMany(p => p.RelatedCountries);
        }

        );
        modelBuilder.Entity<Articles>().OwnsMany(p => p.RelatedResources, a =>
        {
            a.ToJsonProperty("RelatedArticles");
            a.OwnsMany(p => p.RelatedCountries);
        }

        );
        modelBuilder.Entity<Articles>().OwnsOne(p => p.Provisions);
        modelBuilder.Entity<Articles>().OwnsOne(p => p.ResourceGroup);
        modelBuilder.Entity<Articles>().OwnsOne(p => p.Disclaimer);

Спасибо @AndriySvyryd за документацию: person Saiteja Prattipati    schedule 06.03.2020

comment
Большинство этих средств навигации отсутствует на Articles. Но да, это лучше, если вам не нужно переопределять теневые ПК по умолчанию. - person Andriy Svyryd; 08.03.2020

Вам необходимо указать составной FK, поскольку у принципала есть составной PK и сначала объявить свойство shadow:

modelBuilder.Entity<Articles>().Property(e => e.LanguageId).HasConversion(converter);
modelBuilder.Entity<Articles>().HasPartitionKey(o => o.LanguageId);
modelBuilder.Entity<Articles>()
    .OwnsMany(p => p.RelatedCountries, a =>
    {
        a.WithOwner().HasForeignKey("Articlesid");
        a.Property<int>("id");
        a.Property(o => o.IdVal);
    })
    .OwnsMany(p => p.RelatedArticles, a =>
    {
        a.WithOwner().HasForeignKey("Articlesid");
        a.Property<int>("id");
        a.Property(o => o.ArticleId);
        a.Property(o => o.Title);
        a.Property(o => o.PublishedDate);

        a.OwnsMany(p => p.RelatedCountries, a =>
        {
            a.Property<int>("RelatedArticlesSchemaArticlesidid");
            a.WithOwner().HasForeignKey("RelatedArticlesSchemaArticlesid", "RelatedArticlesSchemaArticlesidid");
            a.Property<int>("id");
            a.Property(o => o.IdVal);
        });
    })
    .OwnsMany(p => p.RelatedResources, a =>
    {
        a.WithOwner().HasForeignKey("Articlesid");
        a.Property<int>("id");
        a.Property(o => o.ArticleId);
        a.Property(o => o.Title);
        a.Property(o => o.PublishedDate);

        a.OwnsMany(p => p.RelatedCountries, a =>
        {
            a.Property<int>("RelatedArticlesSchemaArticlesidid");
            a.WithOwner().HasForeignKey("RelatedArticlesSchemaArticlesid", "RelatedArticlesSchemaArticlesidid");
            a.Property<int>("id");
            a.Property(o => o.IdVal);
        });
    });
person Andriy Svyryd    schedule 05.03.2020
comment
Спасибо @Andriy Svyryd за ваш ответ. Я попробовал второй вариант и теперь получаю сообщение об ошибке: свойство «RelatedArticlesSchemaArticlesidid» не может быть добавлено к типу «RelatedArticlesSchema.RelatedCountries # RelatedEntityId», потому что не указан тип свойства и нет соответствующего свойства или поля CLR. Чтобы добавить свойство теневого состояния, необходимо указать тип свойства. \ N - person santosh kumar patro; 05.03.2020
comment
Эх, еще нужно указать составной ФК, я обновил код. - person Andriy Svyryd; 06.03.2020