英文:
Azure CosmosDb + EF Core: Can't use embedded collections inside owned properties?
问题
我们正在使用Cosmos DB和EF Core。
我们有一个如下所示的模型:
class Root
{
public Child? Child { get; set; }
}
class Child
{
public List<GrandChild> GrandChildren { get; set; }
}
配置如下:
modelBuilder.Entity<Root>().OwnsOne(x => x.Child);
然而,我无法弄清楚如何配置所拥有的属性Child
内部的GrandChildren
数组。
没有任何配置的情况下,我收到以下错误:
System.InvalidOperationException:无法确定由类型
List<GrandChild>
表示的导航Child.GrandChildren
的关系。要么手动配置关系,要么使用[NotMapped]
属性或在OnModelCreating
中使用EntityTypeBuilder.Ignore
来忽略此属性。
尝试添加配置后:
modelBuilder.Entity<Child>().HasMany(x => x.GrandChildren);
现在我面临不同的错误:
System.NullReferenceException:对象引用未设置为对象的实例。
堆栈跟踪:
InternalEntityTypeBuilder.CreateForeignKey(InternalEntityTypeBuilder
principalEntityTypeBuilder, IReadOnlyList1 dependentProperties, Key principalKey, String propertyBaseName, Nullable
1 required,
ConfigurationSource configurationSource)
InternalEntityTypeBuilder.HasRelationship(EntityType targetEntityType,
Nullable1 navigationToTarget, Nullable
1 inverseNavigation,
Nullable1 setTargetAsPrincipal, ConfigurationSource configurationSource, Nullable
1 required)
InternalEntityTypeBuilder.HasOwnership(TypeIdentity& targetEntityType,
MemberIdentity& navigation, Nullable1 inverse, ConfigurationSource configurationSource) InternalEntityTypeBuilder.HasOwnership(TypeIdentity& typeIdentity, MemberIdentity navigation, ConfigurationSource configurationSource) OwnedNavigationBuilder
2.OwnsManyBuilder[TNewRelatedEntity](TypeIdentity
ownedType, MemberIdentity navigation)
OwnedNavigationBuilder2.OwnsMany[TNewDependentEntity](Expression
1
navigationExpression)
<c.b__13_4(OwnedNavigationBuilder 2 cb) line 39 EntityTypeBuilder
1.OwnsOne[TRelatedEntity](Expression1 navigationExpression, Action
1 buildAction)
ConfigurationDbContext.OnModelCreating(ModelBuilder
modelBuilder) line 32 ModelCustomizer.Customize(ModelBuilder
modelBuilder, DbContext context)
显然,这是EF Core用于Cosmos DB的提供程序的一个限制,拥有的项目不能拥有自己的拥有属性?
英文:
We're using Cosmos db with EF Core.
We have a model like this:
class Root
{
public Child? Child { get; set; }
}
class Child
{
public List<GrandChild> GrandChildren { get; set; }
}
Configured as follows:
modelBuilder.Entity<Root>().OwnsOne(x => x.Child);
However, I can't figure out how to configure the GrandChildren
array within the owned property Child
.
Without any configuration, I get this error:
> System.InvalidOperationException : Unable to determine the relationship represented by navigation 'Child.GrandChildren' of type 'List<GrandChild>'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
After attempting to add configuration:
modelBuilder.Entity<Child>().HasMany(x => x.GrandChildren);
Now I face a different error:
> System.NullReferenceException : Object reference not set to an instance of an object.
>
> Stack Trace:
> InternalEntityTypeBuilder.CreateForeignKey(InternalEntityTypeBuilder
> principalEntityTypeBuilder, IReadOnlyList1 dependentProperties, Key
1 required,
> principalKey, String propertyBaseName, Nullable
> ConfigurationSource configurationSource)
> InternalEntityTypeBuilder.HasRelationship(EntityType targetEntityType,
> Nullable1 navigationToTarget, Nullable
1 inverseNavigation,
> Nullable1 setTargetAsPrincipal, ConfigurationSource
1 required)
> configurationSource, Nullable
> InternalEntityTypeBuilder.HasOwnership(TypeIdentity& targetEntityType,
> MemberIdentity& navigation, Nullable1 inverse, ConfigurationSource
2.OwnsManyBuilder[TNewRelatedEntity](TypeIdentity
> configurationSource)
> InternalEntityTypeBuilder.HasOwnership(TypeIdentity& typeIdentity,
> MemberIdentity navigation, ConfigurationSource configurationSource)
> OwnedNavigationBuilder
> ownedType, MemberIdentity navigation)
> OwnedNavigationBuilder2.OwnsMany[TNewDependentEntity](Expression
1
> navigationExpression)
> <>c.<OnModelCreating>b__13_4(OwnedNavigationBuilder2 cb) line 39
1.OwnsOne[TRelatedEntity](Expression
> EntityTypeBuilder1
1 buildAction)
> navigationExpression, Action
> ConfigurationDbContext.OnModelCreating(ModelBuilder
> modelBuilder) line 32 ModelCustomizer.Customize(ModelBuilder
> modelBuilder, DbContext context)
Apparently this is a limitation of EF Core provider for cosmosdb that owned items cannot have owned properties of their own?
答案1
得分: 1
I can't figure out how to configure the GrandChildren
array within the owned property Child
.
I tried with the below code which stores GrandChildren
array within the owned property Child
.
public class YourDbContext : DbContext
{
public DbSet<Root> Roots {get; set;}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var endpoint = "*****";
var key = "******";
var databaseName = "nestedDb";
optionsBuilder.UseCosmos(endpoint, key, databaseName);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Root>().OwnsOne(x => x.Child, cb =>
{
cb.OwnsMany(c => c.GrandChildren);
});
}
}
class Program
{
static void Main(string[] args)
{
using (var dbContext = new YourDbContext())
{
dbContext.Database.EnsureCreated();
var grandChild1 = new GrandChild { Id = 1, Name = "Pavan", Age = 25 };
var grandChild2 = new GrandChild { Id = 2, Name = "Balaji", Age = 20 };
var child = new Child
{
GrandChildren = new List<GrandChild> { grandChild1, grandChild2 }
};
var root = new Root
{
Child = child
};
dbContext.Roots.Add(root);
dbContext.SaveChanges();
Console.WriteLine("Root and related entities saved to Cosmos DB.");
}
}
}
Output:
Explanation:
-
Initially define the Entities such as Root, Child, and GrandChild.
-
YourDbContext
class derives fromDbContext
, which Entity Framework Core provides for interacting with databases. -
The
Roots
property is aDbSet
that represents the database's collection of Root entities. -
OnConfiguring
andOnModelCreating
configures connection details and the relationship betweenRoot
,Child
, andGrandChild
respectively. -
The two
GrandChild
entities are added to the collection ofGrandChildren
of a Child entity. -
The Child entity is allocated to the Child property of the Root object.
-
The data is saved to the Cosmos DB database by using the
dbContext.SaveChanges()
function. -
The
OwnsOne
andOwnsMany
methods in theOnModelCreating
method assist in defining the ownership connections between entities. One Child belongs to The Root, and that Child belongs to numerousGrandChild
entities. -
For further details, please refer to this link.
英文:
>I can't figure out how to configure the GrandChildren
array within the owned property Child
.
I tried with the below code which stores GrandChildren
array within the owned property Child
.
public class YourDbContext : DbContext
{
public DbSet<Root> Roots {get; set;}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var endpoint = "*****";
var key = "******";
var databaseName = "nestedDb";
optionsBuilder.UseCosmos(endpoint, key, databaseName);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Root>().OwnsOne(x => x.Child, cb =>
{
cb.OwnsMany(c => c.GrandChildren);
});
}
}
class Program
{
static void Main(string[] args)
{
using (var dbContext = new YourDbContext())
{
dbContext.Database.EnsureCreated();
var grandChild1 = new GrandChild { Id = 1, Name = "Pavan", Age = 25 };
var grandChild2 = new GrandChild { Id = 2, Name = "Balaji", Age = 20 };
var child = new Child
{
GrandChildren = new List<GrandChild> { grandChild1, grandChild2 }
};
var root = new Root
{
Child = child
};
dbContext.Roots.Add(root);
dbContext.SaveChanges();
Console.WriteLine("Root and related entities saved to Cosmos DB.");
}
}
}
Output:
Explanation:
-
Initially define the Entities such as Root, Child and GrandChild.
-
YourDbContext
class derives fromDbContext
, which Entity Framework Core provides for interacting with databases. -
The
Roots
property is aDbSet
that represents the database's collection of Root entities. -
OnConfiguring
andOnModelCreating
configuresconnection
details and relationship betweenRoot
,Child
, andGrandChild
respectively. -
The two
GrandChild
entities are added to the collection ofGrandChildren
of a Child entity. -
The Child entity is allocated to the Child property of the Root object.
-
The data is saved to the Cosmos DB database by using the dbContext.SaveChanges() function.
-
The
OwnsOne
andOwnsMany
methods in theOnModelCreating
method assist in defining the ownership connections between entities. One Child belongs to The Root, and that Child belongs to numerousGrandChild
entities. -
For further please refer this link.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论