I agree with kunjee that this is actually not something like Micro-orm. With that said, I can present two possible options ... neither what I would recommend in a full-blown ORM (EF or nHibernate) as a solution. But perhaps this will help request the best options.
Option 1 Create the line “Where clause” using reflection to preserve some “type safety”. You still need to write a little SQL.
Example
var jn = new JoinSqlBuilder<Table1, Table2>(); jn = jn.Join<Table1, Table2>(s => s.Column1, d => d.Field1);
Helper class
public static class SqlHelper { public static string ToSqlField<T>(Expression<Func<T, object>> expression) { //This should return something like 'Table1.Column1' return typeof(T).Name + "." + GetMemberInfo(expression).Name; } // Stolen from FluentNHibernate.ReflectionUtility public static MemberInfo GetMemberInfo<TEntity>(Expression<Func<TEntity, object>> expression) { MemberInfo memberInfo = null; switch (expression.Body.NodeType) { case ExpressionType.Convert: { var body = (UnaryExpression)expression.Body; if (body.Operand is MethodCallExpression) { memberInfo = ((MethodCallExpression)body.Operand).Method; } else if (body.Operand is MemberExpression) { memberInfo = ((MemberExpression)body.Operand).Member; } } break; case ExpressionType.MemberAccess: memberInfo = ((MemberExpression)expression.Body).Member; break; default: throw new ArgumentException("Unsupported ExpressionType", "expression"); } if (memberInfo == null) { throw new ArgumentException("Could not locate MemberInfo.", "expression"); } return memberInfo; } }
Option 2 - Mess / Mute your classes and disable table prefixes in ExpressionVisitor to allow the creation of the correct SQL. This will explode completely if 2 classes have the same property and are used in the Where clause.
//Modify Table1 to include a reference to Table2 public class Table1 { public string Column1 { get; set; } public string Column2 { get; set; } [ServiceStack.DataAnnotations.Ignore] public Table2 Table2 { get; set; } } var ev = OrmLiteConfig.DialectProvider.ExpressionVisitor<Table1>(); ev.PrefixFieldWithTableName = false; var jn = new JoinSqlBuilder<Table1, Table2>(); jn = jn.Join<Table1, Table2>(s => s.Column1, d => d.Field1); ev.Where(x => x.Column1 == "1"); ev.Where(x => x.Column2 == "2" || ((Table2)x.Table2).Column3 == "3"); //do cast to avoid InvalidOperationException var sql = jn.ToSql() + ev.WhereExpression;
source share