Ответ 1
Роуэн Миллер (менеджер программ для Entity Framework в Microsoft) недавно опубликовала хорошее решение для этого, которое использует Interceptors. По общему признанию, это справедливо только в EF 6.1+. Его сообщение посвящено завершающим строкам в соединениях, но в основном решение, применяемое, аккуратно удаляет завершающие строки из всех свойств строки в ваших моделях автоматически, без заметного влияния на производительность.
Исходное сообщение в блоге: Работа с конечными пробелами в строковых соединениях
Соответствующий код переупорядочивается здесь, но я рекомендую вам прочитать его сообщение в блоге. (Также, если вы используете 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);
}
}
}
}
Rowan продолжает: "Теперь, когда у нас есть перехватчик, нам нужно сказать EF, чтобы он его использовал. Это лучше всего сделать с помощью Code-Based Configuration. Мы можем просто отбросить следующий класс в той же сборке/проекте, что и наш контекст и EF подберет его".
using System.Data.Entity;
namespace FixedLengthDemo
{
public class MyConfiguration : DbConfiguration
{
public MyConfiguration()
{
AddInterceptor(new StringTrimmerInterceptor());
}
}
}