[英]How to Convert Lambda Expression To Sql?
我正在開發一個小框架來訪問數據庫。 我想添加一個使用lambda表達式進行查詢的功能。 我該怎么做呢?
public class TestModel
{
public int Id {get;set;}
public string Name {get;set;}
}
public class Repository<T>
{
// do something.
}
例如:
var repo = new Repository<TestModel>();
var query = repo.AsQueryable().Where(x => x.Name == "test");
// This query must be like this:
// SELECT * FROM testmodel WHERE name = 'test'
var list = query.ToDataSet();
// When I call ToDataSet(), it will get the dataset after running the made query.
繼續創建一個LINQ Provider (我相信你不想這樣做)。
這是很多工作,所以也許你只想使用NHibernate或Entity Framework或類似的東西。
如果您的查詢相當簡單,也許您不需要一個完整的LINQ提供程序。 看看Expression Trees (LINQ Providers使用)。
你可以破解這樣的東西:
public static class QueryExtensions
{
public static IEnumerable<TSource> Where<TSource>(this Repo<TSource> source, Expression<Func<TSource, bool>> predicate)
{
// hacks all the way
dynamic operation = predicate.Body;
dynamic left = operation.Left;
dynamic right = operation.Right;
var ops = new Dictionary<ExpressionType, String>();
ops.Add(ExpressionType.Equal, "=");
ops.Add(ExpressionType.GreaterThan, ">");
// add all required operations here
// Instead of SELECT *, select all required fields, since you know the type
var q = String.Format("SELECT * FROM {0} WHERE {1} {2} {3}", typeof(TSource), left.Member.Name, ops[operation.NodeType], right.Value);
return source.RunQuery(q);
}
}
public class Repo<T>
{
internal IEnumerable<T> RunQuery(string query)
{
return new List<T>(); // run query here...
}
}
public class TestModel
{
public int Id { get; set; }
public string Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
var repo = new Repo<TestModel>();
var result = repo.Where(e => e.Name == "test");
var result2 = repo.Where(e => e.Id > 200);
}
}
請不要使用它。 這只是一個快速而骯臟的例子,可以分析表達式樹來創建SQL語句。
為什么不使用Linq2Sql,NHibernate或EntityFramework ...
如果你想做的事情
db.Employee
.Where(e => e.Title == "Spectre")
.Set(e => e.Title, "Commander")
.Update();
要么
db
.Into(db.Employee)
.Value(e => e.FirstName, "John")
.Value(e => e.LastName, "Shepard")
.Value(e => e.Title, "Spectre")
.Value(e => e.HireDate, () => Sql.CurrentTimestamp)
.Insert();
要么
db.Employee
.Where(e => e.Title == "Spectre")
.Delete();
然后看看這個, BLToolkit
你可能想看看http://iqtoolkit.codeplex.com/這是非常復雜的,我不建議你從頭開始構建一些東西。
我只是寫了一些接近dkons的答案我還是會添加它。 只是使用流暢的界面而已。
public class Query<T> where T : class
{
private Dictionary<string, string> _dictionary;
public Query()
{
_dictionary = new Dictionary<string, string>();
}
public Query<T> Eq(Expression<Func<T, string>> property)
{
AddOperator("Eq", property.Name);
return this;
}
public Query<T> StartsWith(Expression<Func<T, string>> property)
{
AddOperator("Sw", property.Name);
return this;
}
public Query<T> Like(Expression<Func<T, string>> property)
{
AddOperator("Like", property.Name);
return this;
}
private void AddOperator(string opName, string prop)
{
_dictionary.Add(opName,prop);
}
public void Run(T t )
{
//Extract props of T by reflection and Build query
}
}
讓我們說你有一個類似的模型
class Model
{
public string Surname{ get; set; }
public string Name{ get; set; }
}
您可以將其用作:
static void Main(string[] args)
{
Model m = new Model() {Name = "n", Surname = "s"};
var q = new Query<Model>();
q.Eq(x => x.Name).Like(x=>x.Surname).Run(m);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.