我正在使用在C#REST API中使用Entity框架的旧版应用程序上工作。它使用带有Schema架构的Postgresql数据库进行身份验证,每个组织都有自己的架构。有时在生产中,我们会收到有关人们从整个其他架构中查看数据的报告,有时甚至是部分来自其他组织的数据。
请事先为我讲解语法错误。
应用程序使用带有Schema模式的PostgreSQL数据库进行身份验证,每个组织都有自己的模式。
组织架构构造函数的dbcontext需要一个参数,该参数是来自另一个上下文的用户组织,在我们的示例中该上下文可以是x。
实体框架EDMX首先根据第一个组织的数据库生成(所有组织具有相同的结构),并使用System.Data.Entity.Infrastructure.Interception.IDbCommandInterceptor的实现(称为“替换模式Interceptor”)来修改模式命名并因此在实际发送查询之前修改发送到数据库的查询。
每个CRUD请求都基于用户建立自己的上下文,并在呼叫后关闭连接。
遇到此问题的用户永远是同一用户,对于我们开发人员来说,我们永远无法重现此问题,尽管我们在日志中看到用户已在另一模式中写入数据,但我们仍然知道这是一个问题。
我们目前尚无主意,因为我们无法复制它,并且特定用户只有100次中就有1次。
DBContext初始化和简单请求
using (var context = new dbEntities("orgschema_" + db.Organization))
{
/** Any code from lists to single objects possible here */
table1 data = context.table1.Where(x => x.name == testname).FirstOrDefault();
return data;
}
登录时已经设置了用户的组织。
特定的替换模式拦截方法。它将找到所有的orgschema_并替换其背后的组织。
private String ReplaceSchemaGeomerk(String sql)
{
int index = sql.IndexOf("orgschema_");
if (index == -1)
{
return sql;
}
String userStart = sql.Substring(index);
int endIndex = userStart.IndexOf("\"");
if (endIndex == -1)
endIndex = userStart.IndexOf(".");
String user = sql.Substring(index, endIndex);
sql = sql.Replace(user, _newSchema);
return sql;
}
在dbContext构造函数中,执行以下代码。
public dbEntities(string sConnectionString) : base("name=dbEntities")
{
System.Data.Entity.Infrastructure.Interception.DbInterception.Add(new
ReplaceSchemaInterceptor(newSchema: sConnectionString));
}
我希望API始终返回正确组织的数据。但是它不是100/100倍,我们无法复制它。有没有人经历过类似的经历并且可以将我们推向正确的方向?
有关任何其他需要的信息,请随时询问! :)