2015-08-26 10 views
6

से फ़ील्ड मान प्राप्त करने के लिए डायनामिक LINQ क्वेरी क्या यह संभव है?डाटाबेस

Public String Get_Filed_By_Id(string table_Name,String Field_Name,string PK_val) 
{ 
    string strRes=""; 
    using(mydbcontext db=new mydbcontext()) 
    { 
     var x=db.table_Name.Where(p=>p.Id=PK_val).FirstOrDefault().Field_Name; 
     strRes=Convert.Tostring(x); 
    } 
return strRes; 
} 

या

var x=(from o in db.table_Name where o.Id=PK_val select o.Field_Name).FirstOrDefault(); 

यहाँ, मैं Table_Name, Column_Name गुजर रहा हूँ और स्थिति मूल्य (PK_val) एक निश्चित स्थिति (Id=Pk_val) के भीतर Table_Name से Column_Name जाओ करने के लिए।

क्या यह संभव है ??

+0

का उपयोग करना (लेकिन IQueryable के अंदर) : var tableItem = db.table_Name.Where (p => p.Id = PK_val) .FirstOrDefault(); var x = tableItem.GetType()। GetProperty (FieldName) .GetValue (tabelItem, null); – Den

+0

क्या आपने रिपोजिटरी पैटर्न का उपयोग करने पर विचार किया है? – Arash

+0

@Arashjo नहीं, क्या आप मुझे रास्ता दिखा सकते हैं, जवाब दे सकते हैं ?? –

उत्तर

8

में क्या यह संभव है ??

हाँ, यह है।

सबसे पहले, कुछ सहायकों:

using System; 
using System.Linq; 
using System.Linq.Expressions; 
using System.Reflection; 

namespace YourNamespace 
{ 
    internal static class DbHelpers 
    { 
     public static object GetColumnById(this object dbContext, string tableName, string columnName, object id) 
     { 
      var table = (IQueryable)dbContext.GetType().GetProperty(tableName).GetValue(dbContext, null); 
      var row = Expression.Parameter(table.ElementType, "row"); 
      var filter = Expression.Lambda(Expression.Equal(Expression.Property(row, "Id"), Expression.Constant(id)), row); 
      var column = Expression.Property(row, columnName); 
      var selector = Expression.Lambda(column, row); 
      var query = Call(Where.MakeGenericMethod(row.Type), table, filter); 
      query = Call(Select.MakeGenericMethod(row.Type, column.Type), query, selector); 
      var value = Call(FirstOrDefault.MakeGenericMethod(column.Type), query); 
      return value; 
     } 
     private static readonly MethodInfo Select = GetGenericMethodDefinition< 
      Func<IQueryable<object>, Expression<Func<object, object>>, IQueryable<object>>>((source, selector) => 
      Queryable.Select(source, selector)); 
     private static readonly MethodInfo Where = GetGenericMethodDefinition< 
      Func<IQueryable<object>, Expression<Func<object, bool>>, object>>((source, predicate) => 
      Queryable.Where(source, predicate)); 
     private static readonly MethodInfo FirstOrDefault = GetGenericMethodDefinition< 
      Func<IQueryable<object>, object>>(source => 
      Queryable.FirstOrDefault(source)); 
     private static MethodInfo GetGenericMethodDefinition<TDelegate>(Expression<TDelegate> e) 
     { 
      return ((MethodCallExpression)e.Body).Method.GetGenericMethodDefinition(); 
     } 
     private static object Call(MethodInfo method, params object[] parameters) 
     { 
      return method.Invoke(null, parameters); 
     } 
    } 
} 

है और अब अपने समारोह:

public string Get_Field_By_Id(string table_Name, string field_Name, string PK_val) 
{ 
    using (var db = new mydbcontext()) 
     return Convert.ToString(db.GetColumnById(table_Name, field_Name, PK_val)); 
} 
1

वास्तव में EntityFramework (जहां तक ​​मुझे पता है) के साथ यह वास्तव में संभव नहीं है। यदि आपको केवल इसके नाम से फ़ील्ड की आवश्यकता है, तो आप @ डेन के प्रस्तावित समाधान का उपयोग कर सकते थे। लेकिन आप पैरामीटर के रूप में टेबल नाम भी निर्दिष्ट करना चाहते हैं। तो मैं आपको मानक एसक्यूएल कनेक्टर एपीआई का उपयोग करने का सुझाव देता हूं, और आपके द्वारा प्रदान किए गए पैरामीटर के साथ क्वेरी स्ट्रिंग का निर्माण करता हूं।

मानक एसक्यूएल कनेक्टर एपीआई के उपयोग के लिए this link देखें।

0

नहीं, लेकिन इस तरह से

Public String Get_Filed_By_Id(string table_Name,String Field_Name,string PK_val) 
{ 
    string strRes=""; 
    using(mydbcontext db=new mydbcontext()) 
    { 
     var x=db.table_Name.Where(p=>p.Id=PK_val).Select(b=>b.Field_Name).FirstOrDefault(); 
     strRes=Convert.Tostring(x); 
    } 
return strRes; 
} 
+0

काम नहीं करेगा, मैं 'पैरामीटर' और 'फील्ड_वल्यू' को 'पैरामीटर' –

+0

के रूप में पास करने का प्रयास कर रहा हूं, फिर क्वेरी का उपयोग करें, जैसे db.database.ExecuteSQLQuery या ऐसा कुछ जो स्ट्रिंग लेता है (क्वेरी) पैरामीटर के रूप में। – Lali

+0

मैं इस तरह से विश्वास करता हूं, लेकिन अनुमान लगाया कि यह व्यापक होगा, लेकिन मैं रास्ता देखना चाहता हूं। –

1

मैं भी इस सवाल का था, मैं जानता हूँ कि यह नहीं है कि वास्तव में आप क्या चाहते हैं और आप और अधिक कोड लिखने की जरूरत है लेकिन यह उन लोगों की तुलना में बहुत साफ है जिन्हें आप लिखना चाहते हैं।
भंडार पैटर्न का उपयोग
प्रत्येक तालिका के लिए आपके पास मॉडल श्रेणी और रिपोजिटरी कक्षा होनी चाहिए।
इस कोड पर विचार करें (अपने प्रोजेक्ट में से एक से इस कोड)
यह मेरी टिप्पणी तालिका है (के साथ या बिना नेविगेशन संपत्ति इस कुछ भी हो सकता)

public sealed class Comment 
{ 
    public string CommentText { get; set; } 
    public DateTime PostDate { get; set; } 
    public int PostId { get; set; } 
    public int? PageId { get; set; } 
    public Page Page { get; set; } 
    public User User { get; set; } 
    public string UserId { get; set; } 
    public int? ParentId { get; set; } 
    public Comment[] ChildComments { get; set; } 
} 

RepositoryComment

public sealed class CommentRepository : BaseRepository<Comment> 
{ 
    public CommentRepository(BabySitterContext context) 
     : base(context) 
    { 
    } 
} 

और एक आधार कक्षा जिसे आप टेबल नाम (यहां मॉडल) और फ़ील्ड के साथ अपनी क्वेरी भेजते हैं (आप अधिक कार्यक्षमता के लिए क्लैस का विस्तार कर सकते हैं)

public class BaseRepository<T> where T : class 
{ 
    protected BabySitterContext Context; 
    private readonly PluralizationService _pluralizer = PluralizationService.CreateService(CultureInfo.GetCultureInfo("en")); 
    public BaseRepository(BabySitterContext context) 
    { 
     this.Context = context; 
    } 
    public bool Add(T t) 
    { 
     Context.Set<T>().Add(t); 
     Context.SaveChanges(); 
     return true; 
    } 
    public bool Update(T t) 
    { 
     var entityName = GetEntityName<T>(); 

     object originalItem; 
     var key = ((IObjectContextAdapter)Context).ObjectContext.CreateEntityKey(entityName, t); 
     if (((IObjectContextAdapter)Context).ObjectContext.TryGetObjectByKey(key, out originalItem)) 
     { 
      ((IObjectContextAdapter)Context).ObjectContext.ApplyCurrentValues(key.EntitySetName, t); 
     } 
     Context.SaveChanges(); 
     return true; 
    } 
    public void Attach(T t) 
    { 
     if (t == null) 
     { 
      throw new ArgumentNullException("t"); 
     } 

     Context.Set<T>().Attach(t); 
     Context.SaveChanges(); 
    } 
    public void Remove(T t) 
    { 
     if (t == null) 
     { 
      throw new ArgumentNullException("t"); 
     } 
     Context.Set<T>().Remove(t); 
     Context.SaveChanges(); 
    } 
    public IEnumerable<T> Get(Expression<Func<T, bool>> filter = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, string includeProperties = "") 
    { 
     IQueryable<T> query = Context.Set<T>(); 

     if (filter != null) 
     { 
      query = query.Where(filter.Expand()); 
     } 

     foreach (var includeProperty in includeProperties.Split 
      (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) 
     { 
      query = query.Include(includeProperty); 
     } 

     if (orderBy != null) 
     { 
      return orderBy(query).ToList(); 
     } 
     else 
     { 
      return query.ToList(); 
     } 
    } 
    private string GetEntityName<TEntity>() where TEntity : class 
    { 
     return string.Format("{0}.{1}", ((IObjectContextAdapter)Context).ObjectContext.DefaultContainerName, _pluralizer.Pluralize(typeof(TEntity).Name)); 

    } 

    public virtual IEnumerable<T> GetByBusinessKey(T entity) 
    { 
     return null; 
    } 
}  

किसी अन्य तालिका के लिए केवल आपके कार्यक्षमता उस तरह मन में पहली बात यह है प्रतिबिंब है की जरूरत है आधार वर्ग

से तो inherite मॉडल वर्ग और reposiotry बनाने कोड

var context = new BabySitterContext(); 
var _commentRepository = new CommentRepository(context); 
var comment = _commentRepository.Get(x => x.PostId == id).FirstOrDefault(); 
अच्छी तरह से