c# - 如何使用 LINQ 动态查询不同的表?

标签 c# linq entity-framework dbcontext

所以我不确定你是否可以这样做,但我想尽可能避免使用 SQL 字符串。我想用 Linq/DbContexts 做的是以下可以用 SQL 轻松完成的事情:

string sql = "UPDATE " + tableName + " SET Status=0 WHERE Id=" + formId.ToString();

我可以很容易地将它放入一个循环中,其中 tableName 和 formId 是动态给出的并且执行没有问题。

我有多个 DbContext,所以我不知道有什么方法可以做类似的事情:

var db = new *dynamicallyChosenContext*()

var query = from p in db.*dynamicallyChosenAlso*
            where p.Id == formId
            select p;

foreach (var result in query)
{
    result.Status = 0;
}

db.SaveChanges()

感谢您的帮助!

最佳答案

这是一段工作代码,可以在运行时从不同的上下文更新不同的表,而无需使用反射。

namespace DemoContexts
{
    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Linq;


    public interface IThing
    {
        int Id { get; set; }
        int Status { get; set; }
    }

    public class FirstPersonThing : IThing
    {
        [System.ComponentModel.DataAnnotations.Key]
        public int Id { get; set; }
        public int Status { get; set; }
        public string Foo { get; set; }
    }

    public class SecondPersonThing : IThing
    {
        [System.ComponentModel.DataAnnotations.Key]
        public int Id { get; set; }
        public int Status { get; set; }
        public string Bar { get; set; }
    }

    public class FirstContext : DbContext
    {
        public FirstContext() : base("FirstContext") { }
        public DbSet<FirstPersonThing> MyThings { get; set; }
        public DbSet<SecondPersonThing> YourThings { get; set; }
    }

    public class SecondContext : DbContext
    {
        public SecondContext() : base("SecondContext") { }
        public DbSet<FirstPersonThing> MyThings { get; set; }
        public DbSet<SecondPersonThing> YourThings { get; set; }
    }


    class Program
    {
        static void Main(string[] args)
        {
            int contextType = 1;
            int thingType = 1;

            DbContext db = RunTimeCreatedContext(contextType);
            IQueryable<IThing> collection = RunTimeCreatedCollection(db, thingType);

            UpdateRuntimeDeterminedThings(db, collection, 1);

            Console.ReadLine();
        }

        public static void UpdateRuntimeDeterminedThings(DbContext db, 
                                               IQueryable<IThing> collection, 
                                               int formId)
        {
            var querySet = collection.Where(p => p.Id == formId).ToList();
            foreach (var result in querySet)
            {
                result.Status = 0;
            }

            db.SaveChanges();
        }

        static DbContext RunTimeCreatedContext(int contextType)
        {
            if (contextType == 0)
            {
                return new FirstContext();
            }
            else
            {
                return new SecondContext();
            }
        }

        static IQueryable<IThing> RunTimeCreatedCollection(DbContext db, int thingType)
        {
            if (thingType == 0)
            {
                return db.Set(typeof(FirstPersonThing)) as IQueryable<IThing>;
            }
            else
            {
                return db.Set<SecondPersonThing>();
            }
        }
    }
}

首先要注意的是,所有这些都是静态类型的,因此要对不同类型的对象执行通用查询,这些对象必须具有共同的属性签名,这在概念上在 IThing 接口(interface)中表达。

要注意的第二件事是 IQueryable 是如何生成的。它由 DbContext.Set Method (Type) 生成在第一个实例中(对于 FirstPersonThings),它是由 DbContext.Set<TEntity> Method 生成的在第二种情况下。第一个使用在运行时确定的类型并需要强制转换(但在运行时使用传递类型可能很有用),第二个使用泛型并且类型在编译时确定。显然,此功能还有许多其他工作方式。

最后,UpdateRuntimeDeterminedThings 方法起作用了,因为它使用了跨类型共享的属性和方法(通过基本类型/继承或通过接口(interface)的实现)。

这些实际上都不是动态编程(使用动态类型是可能的),我使用术语运行时确定而不是动态来描述它是如何工作的。

关于c# - 如何使用 LINQ 动态查询不同的表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26851167/

相关文章:

c# - 我可以在不创建 DLL 的情况下使用同一项目中的 UserControl 吗?

vb.net - 使用 linq vb.net 进行分组和计数

c# - 使用 MySql 数据库的 MVC 4 中 Entity Framework Code First 中的 Crud 操作

c# - 我怎样才能最好地检查 A xor B 是否为空?

c# - 查找字符串中字符的索引

c# - LINQ 查询后将数据从 var 复制到 DataTable

c# - 在强类型列表上尝试 "where"时出错,错误 CS0103

entity-framework - 如何从 Entity Framework 中的关系对象获取数据?

entity-framework - DBContext DBSet 查询和无跟踪选项

c# - 将图像转换为base64