Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net Npsql:使用EF核心在jsonb列上创建索引_.net_Postgresql_Asp.net Core_Asp.net Core Mvc_Npgsql - Fatal编程技术网

.net Npsql:使用EF核心在jsonb列上创建索引

.net Npsql:使用EF核心在jsonb列上创建索引,.net,postgresql,asp.net-core,asp.net-core-mvc,npgsql,.net,Postgresql,Asp.net Core,Asp.net Core Mvc,Npgsql,我在PostgreSQL:ID(UUID)和Data(jsonb)中有一个标准的NoSQL表。我想在进入数据列的JSON文档的一个属性上创建一个索引。通常我使用EF Core,如下所示: modelBuilder.Entity<T>().HasIndex(e => e.ColumnToPutAnIndexOn); 关于这一问题的调查仍在进行中 除了编写原始SQL语句外,有人知道如何最好地在JSON文档上创建索引吗 谢谢。不幸的是,在jsonb文档中索引属性并不像索引表列那样简

我在PostgreSQL:ID(
UUID
)和Data(
jsonb
)中有一个标准的NoSQL表。我想在进入数据列的JSON文档的一个属性上创建一个索引。通常我使用EF Core,如下所示:

modelBuilder.Entity<T>().HasIndex(e => e.ColumnToPutAnIndexOn);
关于这一问题的调查仍在进行中

除了编写原始SQL语句外,有人知道如何最好地在JSON文档上创建索引吗


谢谢。

不幸的是,在jsonb文档中索引属性并不像索引表列那样简单。。。看一看

为了总结重要信息,如果您只想查询顶级JSON属性,那么列上的GIN索引就足够了。如果您想更深入地查询文档,则必须设置一个表达式索引,这是一个完全不同的beast


由于复杂性和不同的选择,提供的还没有自动为您做任何事情-您必须在迁移中使用原始SQL来定义所需的索引(这样做没有问题-建议这样做)。如果我们能够为不同的jsonb场景提供合理的索引创建逻辑,这种情况在将来可能会发生变化。

Shay,感谢您提供信息。根据答案“这是不可能的”,我对自己说:拿着我的啤酒

所以我做了一些东西。丑陋的东西,但我做到了。它是有效的

以实体本身为例,包含ID和jsonb数据列:

公共类实体,其中T:EntityData
{
[关键]
[数据库生成(DatabaseGeneratedOption.None)]
公共Guid Id{get;set;}
[列(TypeName=“jsonb”)]
公共T数据{get;set;}
公共实体():基()
{
}
}
注意:泛型T是EntityData,它只是一个空基类,用于将来的用途。这可以是任何东西,真的

然后我们可以像这样使用
实体
类:

modelBuilder.Entity<T>().HasIndex(e => e.Data.PropertyToPutAnIndexOn);
Entity userEntity=new Entity();
userEntity.Data.Username=“myusername”;//.Data属性现在是User类型(实际的POCO/Model/JSON文档)
用户类具有以下属性:

公共类用户:EntityData
{
[Index]//自定义IndexAttribute类
公共字符串用户名{get;set;}
}
现在我已经创建了一个ensureIndex()函数,它可以放在自定义DbContext/UnitOfWork类中,也可以放在任何您想要的地方。此函数使用反射并迭代
entity.Data
中实体的属性,并调用原始npgsql命令:

//获取上下文的DbSet属性
PropertyInfo[]dbsets=context.GetType().GetProperties()。其中(x=>x.PropertyType.Name==“DbSet`1”).ToArray();
foreach(数据库集中数据库集的属性信息)
{
//获取DbSet属性的泛型类型。
//在本例中,我们将获得实体类型
string lowerCaseDbSetName=dbset.Name.ToLower();
类型dbsetDataType=dbset.PropertyType.GetGenericArguments()[0];
//尝试获取Entity.Data PropertyInfo
PropertyInfo dataProperty=dbsetDataType.GetProperty(“数据”);
if(dataProperty==null)
{
继续;
}
类型dataPropertyType=dataProperty.PropertyType;
//现在迭代存储在Entity.Data中的POCO/文档的属性
PropertyInfo[]jsonProperties=dataPropertyType.GetProperties().ToArray();
foreach(jsonProperties中的PropertyInfo jsonProperty)
{
//如果我们能找到一个索引。。。。
IndexAttribute属性=attribute.GetCustomAttribute(jsonProperty,typeof(IndexAttribute))作为IndexAttribute;
if(属性==null)
{
继续;
}
字符串camelCaseProperty=jsonProperty.Name.ToCamelCase();
string lowerCaseProperty=jsonProperty.Name.ToLower();
//然后,我们将创建一个SQL语句,在该属性上创建索引。维护IX_DbSet_属性的标准Npgsql命名格式
字符串sql=$“在public上创建索引IX{dbset.Name}{lowerCaseProperty}”。\“{dbset.Name}\”((public.\“{dbset.Name}\”\“Data\”->“{camelCaseProperty}”);”;
int result=context.ExecuteNonQuery(sql);//我的自定义函数在异常时返回-2
如果(结果!=-2)
{
Console.WriteLine(sql);
}
}
}
The expression should represent a simple property access: 't => t.MyProperty'.