c# – 使用Entity Framework 5在SQL Server中连接字符串和数字的
发布时间:2020-12-15 05:39:43 所属栏目:百科 来源:网络整理
导读:出于某种原因,微软决定不支持EF5中的简单连接. 例如 Select(foo = new { someProp = "hello" + foo.id + "/" + foo.bar } 如果foo.id或foo.bar是数字,这将抛出. 我发现的解决方法显然是代码: Select(foo = new { someProp = "hello" + SqlFunctions.StringC
出于某种原因,微软决定不支持EF5中的简单连接.
例如 Select(foo => new { someProp = "hello" + foo.id + "/" + foo.bar } 如果foo.id或foo.bar是数字,这将抛出. 我发现的解决方法显然是代码: Select(foo => new { someProp = "hello" + SqlFunctions.StringConvert((double?)foo.id).Trim() + "/" + SqlFunctions.StringConvert((double?)foo.bar).Trim() } 哪个工作正常,但看起来很可怕. 那么,有更好的方法来实现这个更清洁的代码吗? 解决方法
对于那些感兴趣.
我很生气,缺乏这个功能,我自己使用ExpressionVisitor实现了它. 您现在可以编写原始问题中的代码. using System; using System.Collections; using System.Collections.Generic; using System.Data.Objects.SqlClient; using System.Linq; using System.Linq.Expressions; namespace Crawlr.Web.Code { public static class ObjectSetExExtensions { public static ObjectSetEx<T> Extend<T>(this IQueryable<T> self) where T : class { return new ObjectSetEx<T>(self); } } public class ObjectSetEx<T> : IOrderedQueryable<T> { private readonly QueryProviderEx provider; private readonly IQueryable<T> source; public ObjectSetEx(IQueryable<T> source) { this.source = source; provider = new QueryProviderEx(this.source.Provider); } #region IQueryableEx<T> Members public IEnumerator<T> GetEnumerator() { return source.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return source.GetEnumerator(); } public Type ElementType { get { return source.ElementType; } } public Expression Expression { get { return source.Expression; } } public IQueryProvider Provider { get { return provider; } } #endregion } public class QueryProviderEx : IQueryProvider { private readonly IQueryProvider source; public QueryProviderEx(IQueryProvider source) { this.source = source; } #region IQueryProvider Members public IQueryable<TElement> CreateQuery<TElement>(Expression expression) { Expression newExpression = ExpressionReWriterVisitor.Default.Visit(expression); IQueryable<TElement> query = source.CreateQuery<TElement>(newExpression); return new ObjectSetEx<TElement>(query); } public IQueryable CreateQuery(Expression expression) { Expression newExpression = ExpressionReWriterVisitor.Default.Visit(expression); IQueryable query = source.CreateQuery(newExpression); return query; } public TResult Execute<TResult>(Expression expression) { Expression newExpression = ExpressionReWriterVisitor.Default.Visit(expression); return source.Execute<TResult>(newExpression); } public object Execute(Expression expression) { Expression newExpression = ExpressionReWriterVisitor.Default.Visit(expression); return source.Execute(newExpression); } #endregion } public class ExpressionReWriterVisitor : ExpressionVisitor { public static readonly ExpressionReWriterVisitor Default = new ExpressionReWriterVisitor(); protected override Expression VisitUnary(UnaryExpression node) { if (node.NodeType == ExpressionType.Convert && node.Operand.Type == typeof(int) && node.Type==typeof(object)) { var operand = node.Operand; var stringConvertMethod = typeof(SqlFunctions).GetMethod("StringConvert",new Type[] { typeof(double?) }); var trimMethod = typeof(string).GetMethod("Trim",new Type[] {}); var dOperand = Expression.Convert(operand,typeof(double?)); return Expression.Call(Expression.Call(stringConvertMethod,dOperand),trimMethod); } return base.VisitUnary(node); } } } 用法: var res = model .FooSet .Extend() //<- applies the magic .Select(foo => new { someProp = "hello" + foo.id + "/" + foo.bar } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |