Tôi đồng ý với kunjee rằng đây không thực sự là điều mà Micro-orm phù hợp. Với điều đó đã nói, tôi có thể nghĩ đến 2 lựa chọn tiềm năng ... không phải thứ gì thực sự là thứ tôi muốn giới thiệu trên ORM (EF hoặc nHibernate) đầy đủ như một giải pháp. Nhưng, có lẽ điều này sẽ giúp thu hút các lựa chọn tốt hơn.
Tùy chọn 1 - Xây dựng chuỗi 'Where clause string' bằng cách sử dụng sự phản chiếu để giữ an toàn kiểu '. Bạn sẽ vẫn cần phải viết một chút SQL.
Ví dụ
var jn = new JoinSqlBuilder<Table1, Table2>();
jn = jn.Join<Table1, Table2>(s => s.Column1, d => d.Field1);
//using ExpressionVisitor because I didn't see a way to allow a Where clause string parameter to be used
//on a JoinSqlBuilder method
var ev = OrmLiteConfig.DialectProvider.ExpressionVisitor<Table1>();
ev.Where(
SqlHelper.ToSqlField<Table1>(x => x.Column1) + "={0} AND (" +
SqlHelper.ToSqlField<Table1>(x => x.Column2) + "={1} OR " + SqlHelper.ToSqlField<Table2>(x => x.Column3) +
"={2})", "1", "2", "3");
var sql = jn.ToSql() + ev.WhereExpression;
Helper Lớp
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;
}
}
Lựa chọn 2 - Mess/ô nhiễm Lớp học của bạn và tắt các tiền tố bảng trong một ExpressionVisitor cho phép SQL đúng là được tạo. Điều này sẽ hoàn toàn nổ tung nếu 2 lớp có cùng thuộc tính và được sử dụng trong mệnh đề Where.
//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;
Theo như tôi biết nó không có ở đó. Và Micro-orm là tốt cho loại này hoặc những thứ. Bạn có thể quay lại truy vấn cũ đơn giản cho các tình huống phức tạp. Hy vọng rằng bạn biết truy vấn() chức năng bạn có thể sử dụng và vượt qua một tham số nếu bạn muốn. –
kunjee