从数据库中获取字段值的动态LINQ查询

本文关键字:动态 LINQ 查询 字段 数据库 获取 | 更新日期: 2023-09-27 18:09:55

可以吗?

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

这是可能的吗?

从数据库中获取字段值的动态LINQ查询

这是可能的吗?

是的,它是。

首先是一些帮助:

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

这是不可能与EntityFramework实际上(据我所知)。如果您只需要字段的名称,那么您可以使用@Den提出的解决方案。但是您还需要指定表名作为参数。因此,我建议您使用标准的Sql Connector api,并使用您提供的参数构建查询字符串。

查看此链接以获取标准sql连接器api的使用

我也有这个问题,我知道这不是你想要的,你需要写更多的代码,但它比你想写的要干净得多。
使用存储库模式
对于每个表,你都应该有一个模型类和一个存储库类。考虑这段代码(这段代码来自我的一个项目)
这是我的评论表(这可以是任何有或没有导航属性)

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

对于任何其他表,只需创建模型类和存储库,然后从基类继承

使用代码

 var context = new BabySitterContext();
 var  _commentRepository = new CommentRepository(context);
 var comment = _commentRepository.Get(x => x.PostId == id).FirstOrDefault();

不,但以这种方式

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