如何配置实体框架自动修剪检索映射到CHAR(N)领域的具体列的值? [英] How can I configure Entity Framework to automatically trim values retrieved for specific columns mapped to char(N) fields?

查看:331
本文介绍了如何配置实体框架自动修剪检索映射到CHAR(N)领域的具体列的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正与一中的所有文本值均存储第三方数据库char(N)。其中一些文本值是主键,而其他人都只是正常的人类可读的文本。对于后者,我想检索到的值进行自动微调。

I'm working with a third-party database in which all text values are stored as char(n). Some of these text values are primary keys, whereas others are just normal human-readable text. For the latter, I want retrieved values to be automatically trimmed.

我知道我可以添加修剪来我的所有的LINQ to Entities查询,但这是凌乱的,不可靠和难以维护。我想以某种方式配置实体框架自动修剪从特定的列中检索值。

I know I can add Trim to all of my LINQ to Entities queries, but this is messy, unreliable and unmaintainable. I would like to somehow configure Entity Framework to automatically trim values retrieved from specific columns.

不过,我不知道如何做到这一点。我使用的是EF英孚的流畅API。我认为到目前为止最接近的事是创造额外的属性来包装不动产与修剪方法调用,但这是凌乱的,仍然不是很维护。我也preFER的调整,从而出现在数据库中,而不是应用程序。

However, I don't know how to do this. I'm using EF's fluent API. The closest thing I've thought of so far is creating additional properties to wrap the real properties with Trim method calls, but this is messy and still not very maintainable. I would also prefer for the trimming to occur in the database rather than the application.

推荐答案

罗恩·米勒(项目经理实体框架微软)最近发布了一个很好的解决这个它使用拦截器。诚然,这是只有在EF有效6.1+。他的文章是关​​于尾随联接字符串,但基本上,适用整齐的解决方案删除尾随从所有的字符串属性的字符串你的模型,自动完成,无需显着影响性能。

Rowan Miller (program manager for Entity Framework at Microsoft) recently posted a good solution to this which uses Interceptors. Admittedly this is only valid in EF 6.1+. His post is about trailing strings in joins, but basically, the solution as applied neatly removes trailing strings from all of the string properties in your models, automatically, without noticeably affecting performance.

原的博客文章:在周围工作尾随空白问题字符串连接

相关code在这里转贴,但我建议你阅读他的博客。 (另外,如果你使用EF,你应该反正阅读他的博客)。

The relevant code is reposted here, but I encourage you to read his blog post. (Also if you use EF, you should read his blog anyway).

using System.Data.Entity.Core.Common.CommandTrees;
using System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder;
using System.Data.Entity.Core.Metadata.Edm;
using System.Data.Entity.Infrastructure.Interception;
using System.Linq;

namespace FixedLengthDemo
{
    public class StringTrimmerInterceptor : IDbCommandTreeInterceptor
    {
        public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext)
        {
            if (interceptionContext.OriginalResult.DataSpace == DataSpace.SSpace)
            {
                var queryCommand = interceptionContext.Result as DbQueryCommandTree;
                if (queryCommand != null)
                {
                    var newQuery = queryCommand.Query.Accept(new StringTrimmerQueryVisitor());
                    interceptionContext.Result = new DbQueryCommandTree(
                        queryCommand.MetadataWorkspace,
                        queryCommand.DataSpace,
                        newQuery);
                }
            }
        }

        private class StringTrimmerQueryVisitor : DefaultExpressionVisitor
        {
            private static readonly string[] _typesToTrim = { "nvarchar", "varchar", "char", "nchar" };

            public override DbExpression Visit(DbNewInstanceExpression expression)
            {
                var arguments = expression.Arguments.Select(a =>
                {
                    var propertyArg = a as DbPropertyExpression;
                    if (propertyArg != null && _typesToTrim.Contains(propertyArg.Property.TypeUsage.EdmType.Name))
                    {
                        return EdmFunctions.Trim(a);
                    }

                    return a;
                });

                return DbExpressionBuilder.New(expression.ResultType, arguments);
            }
        }
    }
}

罗文继续说:现在,我们有一个拦截器,我们需要告诉EF使用它这是最好通过$ C $基于C的配置完成,我们可以刚落下面的类在同一个组装/项目中。我们的背景和EF将会把它捡起来。

Rowan continues: "Now that we have an interceptor, we need to tell EF to use it. This is best done via Code-Based Configuration. We can just drop the following class in the same assembly/project as our context and EF will pick it up."

using System.Data.Entity;

namespace FixedLengthDemo
{
    public class MyConfiguration : DbConfiguration
    {
        public MyConfiguration()
        {
            AddInterceptor(new StringTrimmerInterceptor());
        }
    }
}

这篇关于如何配置实体框架自动修剪检索映射到CHAR(N)领域的具体列的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆