gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-03 13:14:53 25 4
gpt4 key购买 nike

所以我不确定你是否可以这样做,但我想尽可能避免使用 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com