2012-06-11 6 views
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. 
+0

http://www.linqpad.net/ आप मदद कर सकता है। –

+1

आपको ओ/आरएम फ्रेमवर्क का उपयोग करना चाहिए जो LINQ से SQL या Entity Framework जैसे अभिव्यक्तियों पर LINQ को सक्षम बनाता है। – Steven

+1

क्या आप एक [क्वेरी प्रदाता] (http://msdn.microsoft.com/en-us/library/system.linq.iqueryprovider.aspx) को कार्यान्वित करना चाहते हैं? – phg

उत्तर

12

पर जाओ और बनाने के एक LINQ Provider (मुझे यकीन है कि तुम वैसे भी यह करने के लिए, नहीं करना चाहती हूँ)।

यह बहुत काम है, तो शायद आप NHibernate या Entity Framework या ऐसा कुछ उपयोग करना चाहते हैं।

यदि आपके प्रश्न सरल हैं, तो आपको एक पूर्ण उड़ा LINQ प्रदाता की आवश्यकता नहीं है। Expression Trees पर देखें (जो LINQ प्रदाता द्वारा उपयोग किया जाता है)।

आप हैक कर सकते हैं कुछ इस तरह:

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

कृपया इस का उपयोग नहीं करते के रूप में यह है। यह सिर्फ एक त्वरित और गंदा उदाहरण है कि एसक्यूएल स्टेटमेंट बनाने के लिए अभिव्यक्ति पेड़ों का विश्लेषण कैसे किया जा सकता है।

न सिर्फ Linq2Sql, NHibernate या EntityFramework ... का उपयोग क्यों

+0

मैंने linq प्रदाता का उपयोग करने की कोशिश की। मैंने समझाया। लेकिन यह काम नहीं किया। बहुत अधिक कक्षाएं हैं। क्या मैं एक और आसान तरीका नहीं करता? – sinanakyazici

+0

@sinanakyazici मैंने आपके लिए – sloth

+0

@sinanakyazici हां, एक linq प्रदाता बनाने जटिल बनाने के लिए एक साधारण उदाहरण जोड़ा है। यही कारण है कि अगर लोग नहीं चाहते हैं, तो लोग खुद को नहीं लिखते हैं, बल्कि मौजूदा लोगों का उपयोग करते हैं। – sloth

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/ पर देखना चाहते हैं जो बहुत जटिल है और मैं आपको स्क्रैच से कुछ बनाने की सलाह नहीं देता हूं।

मैंने अभी डॉकन के जवाब के करीब कुछ लिखा है, मैं इसे वैसे भी जोड़ूंगा। बस धाराप्रवाह इंटरफ़ेस का उपयोग करके और कुछ नहीं।

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


     } 
+0

Property.Name हमेशा शून्य है। इसे निकालने के लिए आपको निम्न कार्य करना होगा: var अभिव्यक्ति = (सदस्य एक्सप्रेशन) संपत्ति। बॉडी; स्ट्रिंग नाम = अभिव्यक्ति। सदस्य। नाम; –

+0

और एक और बात यह है कि आप डिक सोच का उपयोग नहीं कर सकते हैं अगर आपके पास दो बार "पसंद" है, तो फिर क्या खुशी होगी –

संबंधित मुद्दे