如何使用 entity framework 核心 3.1.1 为拥有的实体类型设置复合主键?
How to set the composite primary key for owned entity types using entity framework core 3.1.1?
我正在使用 asp.net core 3.1 与 efcore 3.1.1 和 Microsoft.EntityFrameworkCore.Cosmos 3.1.1 来开发 graphql API。
这是我的代码详情:
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"
}
]
}
我收到下面提到的错误:
The property 'RelatedArticlesSchemaArticlesidid' cannot be added to the type 'RelatedArticlesSchema.RelatedCountries#RelatedEntityId' because there was no property type specified and there is no corresponding CLR property or field. To add a shadow state property the property type must be specified.
任何人都可以帮助我知道如何解决这个问题
你需要指定复合FK,因为主体有复合PK,先声明影子属性:
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);
});
});
您需要更新您的 dbcontext class 如下:
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 提供的文档:
https://github.com/dotnet/efcore/commit/f70c3b62e49169f858c087d0cc22ee3edf307933#diff-4301fc6ef06589dd6e5e63debdd80f68L289
我正在使用 asp.net core 3.1 与 efcore 3.1.1 和 Microsoft.EntityFrameworkCore.Cosmos 3.1.1 来开发 graphql API。
这是我的代码详情:
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"
}
]
}
我收到下面提到的错误:
The property 'RelatedArticlesSchemaArticlesidid' cannot be added to the type 'RelatedArticlesSchema.RelatedCountries#RelatedEntityId' because there was no property type specified and there is no corresponding CLR property or field. To add a shadow state property the property type must be specified.
任何人都可以帮助我知道如何解决这个问题
你需要指定复合FK,因为主体有复合PK,先声明影子属性:
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);
});
});
您需要更新您的 dbcontext class 如下:
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 提供的文档: https://github.com/dotnet/efcore/commit/f70c3b62e49169f858c087d0cc22ee3edf307933#diff-4301fc6ef06589dd6e5e63debdd80f68L289