복붙노트

[SQL] 어떻게 엔티티 프레임 워크는 문자 (N) 필드에 매핑 특정 컬럼에 대한 검색 자동 트림 값으로 구성 할 수 있습니다?

SQL

어떻게 엔티티 프레임 워크는 문자 (N) 필드에 매핑 특정 컬럼에 대한 검색 자동 트림 값으로 구성 할 수 있습니다?

나는 모든 텍스트 값이 CHAR (n)에 저장되어있는 타사 데이터베이스와 함께 일하고 있어요. 다른 사람들이 단지 정상적인 사람이 읽을 수있는 텍스트 반면 이러한 텍스트 값 중 일부는 기본 키입니다. 후자의 경우, 나는 검색된 값이 자동으로 정돈하고 싶다.

내가 엔티티 쿼리에 대한 내 LINQ의 모든 트림을 추가 할 수 있습니다 알고 있지만,이, 지저분한 신뢰할 수없고 이상 유지할 수 있습니다. 어떻게 든 특정 컬럼에서 검색 자동 트림 값으로 엔티티 프레임 워크를 구성하고 싶습니다.

그러나, 나는이 작업을 수행하는 방법을 모르겠어요. 나는 EF의 유창하게 API를 사용하고 있습니다. 내가 지금까지 생각했습니다 가장 가까운 것은 트림 메서드 호출과 실제 속성을 포장하는 추가 속성을 만들 것입니다, 그러나 이것은 여전히 ​​유지 관리하지 지저분합니다. 트리밍 데이터베이스가 아닌 응용 프로그램에서 발생하는 나는 또한 선호하는 것.

해결법

  1. ==============================

    1.로완 밀러 (마이크로 소프트의 엔티티 프레임 워크 프로그램 매니저)는 최근 인터셉터를 사용하여이에 좋은 솔루션을 기록했다. 틀림없이이 6.1 이상 EF에서만 유효합니다. 자신의 게시물 조인에서 문자열을 후행에 대해이지만, 기본적으로 적용되는 솔루션은 깔끔하게 눈에 띄게 성능에 영향을주지 않고, 자동으로 귀하의 모델 문자열의 모든 속성의 문자열을 후행 제거합니다.

    로완 밀러 (마이크로 소프트의 엔티티 프레임 워크 프로그램 매니저)는 최근 인터셉터를 사용하여이에 좋은 솔루션을 기록했다. 틀림없이이 6.1 이상 EF에서만 유효합니다. 자신의 게시물 조인에서 문자열을 후행에 대해이지만, 기본적으로 적용되는 솔루션은 깔끔하게 눈에 띄게 성능에 영향을주지 않고, 자동으로 귀하의 모델 문자열의 모든 속성의 문자열을 후행 제거합니다.

    원래 블로그 게시물 : 작업 주위에 후행 공백이 문자열에 발행 조인

    관련 코드는 여기에 다시 게시,하지만 난 자신의 블로그 게시물을 읽어 보시기 바랍니다있다. (당신이 EF를 사용하는 경우 또한, 당신은 자신의 블로그 어쨌든을 읽어야합니다).

    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 말할 필요 "와 EF가 선택됩니다.. 로완은 계속된다 그것까지. "

    using System.Data.Entity;
    
    namespace FixedLengthDemo
    {
        public class MyConfiguration : DbConfiguration
        {
            public MyConfiguration()
            {
                AddInterceptor(new StringTrimmerInterceptor());
            }
        }
    }
    
  2. ==============================

    2.대신 개체에 자동 속성의 필드를 백업과 속성을 사용합니다.

    대신 개체에 자동 속성의 필드를 백업과 속성을 사용합니다.

    과 같이, 속성 세터에서 "트림 ()"를 추가 :

        protected string _name;
        public String Name
        {
            get { return this._name; }
            set { this._name = (value == null ? value : value.Trim()); }
        }
    

    난 그냥이 작업을 자동으로 수행하는 것이 내 자신의 POCO 생성기를 썼다,하지만 당신은 그런 옵션이없는 경우, ReSharper에서 두 개의 키 입력과 같은 자동 속성 백업 필드를 추가 할 수 있습니다. 그냥 문자열을 위해 그것을 할, 당신은 (파일 범위에서) 전역을 찾을 수 / 대한 대체 할 수있다 "= 값;" 함께 "value.Trim () = 「.

  3. ==============================

    3.당신이 엔티티 프레임 워크 코어를 사용하는 경우는 다음과 같이 변환을 사용할 수 있습니다 :

    당신이 엔티티 프레임 워크 코어를 사용하는 경우는 다음과 같이 변환을 사용할 수 있습니다 :

    entity.Property(e => e.Name)
                 .HasConversion(
                    new ValueConverter<string, string>(v => v.TrimEnd(), v => v.TrimEnd()));
    
  4. ==============================

    4.데이터베이스에서 트림 문자열 필드와를 가져 그것을 말할 수 엔티티 프레임 워크, 그것은 SQL 문장을 구성하는 방식을 변경 후크를 제공하지 않습니다.

    데이터베이스에서 트림 문자열 필드와를 가져 그것을 말할 수 엔티티 프레임 워크, 그것은 SQL 문장을 구성하는 방식을 변경 후크를 제공하지 않습니다.

    ObjectContext.ObjectMaterialized 이벤트에 문자열 속성을 트리밍 할 수있을 것입니다,하지만 난이 크게 성능에 영향을 미칠 것이라고 생각합니다. (당신이 할 의도 한대로) 또한, 특정 속성에 대해이 작업을 수행하는 경우 - 다른 사람 또는 스위치 코드를 많이 걸릴 것이다. 당신이 (예를 들어, 키 제외) 거의 모든 속성에 대해이 작업을 수행 할 경우 그것은 가치의 시도 될 수있다.

    그렇지 않으면 내가 추가 속성 갈 것입니다.

  5. ==============================

    5.저도 같은 문제가 있었다. 그리고 DbContext이 간단한 방법으로 그것을 해결 :

    저도 같은 문제가 있었다. 그리고 DbContext이 간단한 방법으로 그것을 해결 :

    public partial class MyDbContext : DbContext
    {
        public override int SaveChanges()
        {
            foreach (var entity in this.ChangeTracker.Entries())
            {
                foreach (PropertyEntry property in entity.Properties.ToList().Where(o => !o.Metadata.IsKey()))
                    TrimFieldValue(property);
            }
    
            return base.SaveChanges();
        }
    
        private void TrimFieldValue(PropertyEntry property)
        {
            var metaData = property.Metadata;
            var currentValue = property.CurrentValue == null ? null : property.CurrentValue.ToString();
            var maxLength = metaData.GetMaxLength();
    
            if (!maxLength.HasValue || currentValue == null) return;
    
            if (currentValue.Length > maxLength.Value)
                property.CurrentValue = currentValue.Substring(0, maxLength.Value);
        }       
    }
    
  6. ==============================

    6.열 유형 만 "문자", "VARCHAR"를 포함하기 때문에 내가 스튜어트 Grassie에 의해 주어진 접근 방식을 사용하지만, 처음에는 일을하지 않았다 등 열이 실제로 "문자 (30)", "VARCHAR (10)"이다, 등 내가 일단이 마법처럼 일 다음 라인을 변경!

    열 유형 만 "문자", "VARCHAR"를 포함하기 때문에 내가 스튜어트 Grassie에 의해 주어진 접근 방식을 사용하지만, 처음에는 일을하지 않았다 등 열이 실제로 "문자 (30)", "VARCHAR (10)"이다, 등 내가 일단이 마법처럼 일 다음 라인을 변경!

    에서: 경우 (propertyArg! = NULL && _typesToTrim.Contains (propertyArg.Property.TypeUsage.EdmType.Name))

    에: 경우 (propertyArg! = NULL && _typesToTrim.Any (t => propertyArg.Property.TypeUsage.EdmType.Name.Contains (t)))

    감사 스튜어트!

  7. from https://stackoverflow.com/questions/20133696/how-can-i-configure-entity-framework-to-automatically-trim-values-retrieved-for by cc-by-sa and MIT license