我正在尝试为 Entity Framework 实现数据本地化逻辑。因此,例如,如果查询选择 Title
属性,则在后台它应该根据当前用户文化引用 Title_enGB
或 Title_deCH
列。
为此,我想重写 Entity Framework 中的 DbExpression CommandTrees。我以为这些trees是构建跨数据库插入/更新/选择查询的一种新的通用 .NET 方法。但现在命名空间 System.Data.Metadata
和 System.Data.Common 中的所有相关构造函数/工厂
是内部的! (在 msdn 中记录为公开,例如:System.Data.Entity.dll
中的 .CommandTreesDbExpressionBuilder
)。
有没有人想过使用或不使用查询树重写来实现这种查询操作?
我想要的代码:(public class DbProviderServicesWrapper : DbProviderServices
)
/// <summary>
/// Creates a command definition object for the specified provider manifest and command tree.
/// </summary>
/// <param name="providerManifest">Provider manifest previously retrieved from the store provider.</param>
/// <param name="commandTree">Command tree for the statement.</param>
/// <returns>
/// An exectable command definition object.
/// </returns>
protected override DbCommandDefinition CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree)
{
var originalCommandTree = commandTree as DbQueryCommandTree;
if (originalCommandTree != null)
{
var expression = new MyCustomQueryRewriter(originalTree.MetadataWorkspace).Visit(originalCommandTree.Query);
commandTree = DbQueryCommandTree.FromValidExpression(originalCommandTree.MetadataWorkspace, originalCommandTree.DataSpace, expression);
}
// TODO: UpdateCommand/InsertCommand
var inner = this.Inner.CreateCommandDefinition(providerManifest, commandTree);
var def = new DbCommandDefinitionWrapper(inner, (c, cd) => new DbCommandWrapper(c));
return def;
}
更新
在一个表上有两个标题列并不酷,但它更容易在第一步中实现。稍后我将加入另一个带有本地化字段的表,因此主表将只包含不变数据。
最佳答案
在 .net 中,您有用于处理本地化的 resx 文件。请参阅:What are the benefits of resource(.resx) files?
您的方法存在几个问题:
- 添加额外的语言需要更改数据库
- 来自数据库的数据流量超过需要
我知道这不是您问题的直接答案,但我认为您应该查看 resx 文件。
如果您必须将其存储在数据库中,您可以重新设计数据库:
- 表1:id、文本
- 表2:id、Table1_id、language_code、text
这样一种新语言不需要更改数据库,并且 EF 代码变得更加简单。
关于c# - EntityFramework 查询操作、数据库提供程序包装、数据库表达式树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6369605/