完全的模拟表达式非常困难,因为C#目前不支持自定义操作符,只支持操作符重载(希望C#能够提供操作符自定义,如果有语言支持这个,也请告知),思路其实很简单,就是建立自己的类型,并重载一些操作符,模拟这个的目的就是在实体模型下规避直接写数据库SQL语句,用类似于ESQL,Linq语法完成这个工作,提供开发一个一致的实体应用模型:
1)参数类,用于传递实际参数,最终转换成ADO.Net的命令中需要的参数:
public class Parameter {//没有具体实现,这里只需要模拟 }
2)表达式接口:
public interface IDbExpression { string Expression { get; } Dictionary<string, Parameter> Parameters {get;} }
3)表达式基类:主要是一些操作符号重载,一些无法用表达式的地方定义类似的函数
public class DbExpression : IDbExpression { private StringBuilder _sqlStatement; private Dictionary<string, Parameter> _Parameters; public StringBuilder SQL { get { return _sqlStatement; } } public DbExpression() { _sqlStatement = new StringBuilder(); _Parameters = new Dictionary<string, Parameter>(); } public static DbExpression operator >(DbExpression e1, DbExpression e2) { DbExpression theExp = new DbExpression(); theExp.SQL.AppendLine(e1.Expression + " > " + e2.Expression); theExp.AddParams(e1); theExp.AddParams(e2); return theExp; } public static DbExpression operator <(DbExpression e1, DbExpression e2) { DbExpression theExp = new DbExpression(); theExp.SQL.AppendLine(e1.Expression + " < " + e2.Expression); theExp.AddParams(e1); theExp.AddParams(e2); return theExp; } public static DbExpression operator >=(DbExpression e1, DbExpression e2) { DbExpression theExp = new DbExpression(); theExp.SQL.AppendLine(e1.Expression + " >= " + e2.Expression); theExp.AddParams(e1); theExp.AddParams(e2); return theExp; } public static DbExpression operator <=(DbExpression e1, DbExpression e2) { DbExpression theExp = new DbExpression(); theExp.SQL.AppendLine(e1.Expression + " <= " + e2.Expression); theExp.AddParams(e1); theExp.AddParams(e2); return theExp; } public static DbExpression operator ==(DbExpression e1, DbExpression e2) { DbExpression theExp = new DbExpression(); theExp.SQL.AppendLine(e1.Expression + " = " + e2.Expression); theExp.AddParams(e1); theExp.AddParams(e2); return theExp; } public static DbExpression operator !=(DbExpression e1, DbExpression e2) { DbExpression theExp = new DbExpression(); theExp.SQL.AppendLine(e1.Expression + " != " + e2.Expression); theExp.AddParams(e1); theExp.AddParams(e2); return theExp; } public static DbExpression operator &(DbExpression e1, DbExpression e2) { DbExpression theExp = new DbExpression(); theExp.SQL.AppendLine(e1.Expression + " and " + e2.Expression); theExp.AddParams(e1); theExp.AddParams(e2); return theExp; } public static DbExpression operator |(DbExpression e1, DbExpression e2) { DbExpression theExp = new DbExpression(); theExp.SQL.AppendLine(e1.Expression + " or " + e2.Expression); theExp.AddParams(e1); theExp.AddParams(e2); return theExp; } public DbExpression Parentheses(DbExpression e) { this.SQL.AppendLine("(" + e.Expression + ")"); this.AddParams(e); return this; } public DbExpression Where(DbExpression e1) { this._sqlStatement.AppendLine(" WHERE " + e1.Expression); this.AddParams(e1); return this; } public DbExpression From(params DbExpression[] Tables) { this.SQL.AppendLine(" FROM "); if (Tables != null) { int i = 0; foreach (var item in Tables) { if (i == 0) { _sqlStatement.Append(" " + item.Expression); } else { _sqlStatement.Append("," + item.Expression); } this.AddParams(item); } } return this; } public DbExpression Select(params DbExpression[] Fields) { _sqlStatement.Append(" SELECT "); if (Fields != null) { int i = 0; foreach (var item in Fields) { if (i == 0) { _sqlStatement.Append(" " + item.Expression); } else { _sqlStatement.Append("," + item.Expression); } this.AddParams(item); } } else { _sqlStatement.Append(" * "); } return this; } public void AddParams(DbExpression e) { if (e.Parameters == null) { return; } foreach (var p in e._Parameters) { if(this._Parameters.ContainsKey(p.Key)==false) { this._Parameters.Add(p.Key, p.Value); } } } public void AddParams(IDbExpression e) { if (e.Parameters == null) { return; } foreach (var p in e.Parameters) { if (this._Parameters.ContainsKey(p.Key) == false) { this._Parameters.Add(p.Key, p.Value); } } } public virtual string Expression { get { return _sqlStatement.ToString(); } } public virtual Dictionary<string, Parameter> Parameters { get { return _Parameters; } } }