Вопрос по lambda, asqueryable, c#, linq – Как конвертировать лямбда-выражение в Sql?

5

Я разрабатываю небольшую структуру для доступа к базе данных. Я хочу добавить функцию, которая делает запрос с использованием лямбда-выражения. Как мне это сделать?

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.
@sinanakyazici: Написание собственного провайдера запросов ЧРЕЗВЫЧАЙНО СЛОЖНО !! Не тратьте деньги своего босса на написание своих собственных. Вы все равно потерпите неудачу. Просто поработайте с первой версией Entity Framework (.NET 3.5) (и узнайте, сколько EF1 отстой), чтобы понять, насколько сложно написать собственный движок, который позволяет преобразовывать деревья выражений в SQL. Steven
linqpad.net мог бы помочь тебе. Lukasz Madon
Вы должны использовать инфраструктуру O / RM, которая включает LINQ поверх выражений, например LINQ to SQL или Entity Framework. Steven
Вы хотите реализоватьquery provider? phg
Чтобы получить представление о глубине LINQ, посмотритеthis. phg

Ваш Ответ

3   ответа
2

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

0

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);


        }
И еще одна вещь, которую вы не можете использовать, думайте, если у вас есть «НРАВИТСЯ» два раза, что будет потом
Property.Name всегда равно нулю. Чтобы извлечь его, вам нужно будет сделать следующее: var expression = (MemberExpression) property.Body; строка name = expression.Member.Name;
13

LINQ Provider (Во всяком случае, я уверен, что вы не хотите этого делать).

Это много работы, так что, возможно, вы просто хотите использоватьNHibernate или жеEntity Framework или что-то типа того.

Если ваши запросы довольно просты, возможно, вам не нужен полноценный поставщик LINQ. Посмотри наДеревья выражения (которые используются провайдерами LINQ).

Вы можетеhack что-то вроде этого:

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 ...

Почему я не использую их (Linq2Sql, NHibernate и EntityFR)? Потому что я уже написал в моем ORM. Поэтому я не нуждаюсь в них. sinanakyazici
Я пытался использовать linq провайдера. Я объяснил. Но это не сработало. Есть слишком много класса. Разве я не делаю более простой способ? sinanakyazici
@sinanakyazici Да, создание поставщика linq является сложным. Вот почему люди не пишут свои собственные, если они не обязаны, а вместо этого используют существующие.
Большое спасибо. Вы написали еще один Где (). Но я хочу использовать Where () из Linq. Так что ваши написанные бесполезны для меня. Предположительно, я могу использовать Linq Provider. sinanakyazici
@sinanakyazici Я добавил простой пример, чтобы вы поняли идею

Похожие вопросы