【问题标题】:c# Linq to Sql dynamic Data Context assignmentc# Linq to Sql 动态数据上下文赋值
【发布时间】:2013-07-23 17:04:34
【问题描述】:

`嗨,

有人可以指点一下吗?我有 8 台服务器,每台服务器都有 8 个数据库,它们看起来相同,例如服务器/数据库名称。我们正在谈论数千张桌子。

我使用 sqlmetal.exe 创建我的数据上下文

创建数据上下文后,我将它们导入应用程序,然后在数据库上运行比较脚本以比较结果。

我的问题是在数据上下文之间动态切换。

Datacontext.DAL.DUK1 duk1sdi = new     Datacontext.DAL.DUK1(connectionString);
Datacontext.DAL.DUK3 duk3sdi = new     Datacontext.DAL.DUK3(connectionString);

string fromOne = runQuery(duk1sdi);
string fromThree = runQuery(duk3sdi);

public static string runQuery(DataContext duk)

{
var query =
from result in duk.TableA
select result.Total;

string returnString = query;
return returnString;
}

预定义 duk 时运行的查询没有问题,但是如何定义数据上下文并将其传递给函数?

我得到的错误是:

错误 1 ​​'System.Data.Linq.DataContext' 不包含定义 对于 'TableA' 并且没有扩展方法 'TableA' 接受第一个 可以找到“System.Data.Linq.DataContext”类型的参数(是 您缺少 using 指令或程序集引用?)

【问题讨论】:

    标签: c# linq-to-sql


    【解决方案1】:

    您可以使用GetTable<T> 方法,其中T 是表的类型,例如TableA.

    public static string runQuery(DataContext duk) {
      var table = duk.GetTable<TableA>();
      var query = from result in table select result.Total;
      ...
    }
    

    但是,所有类型的TableA 都必须是相同的类型,严格来说(我很确定)。

    否则,您将需要逐个分支处理每个上下文的逻辑。由于您可以扩展您的DataContext 实例(通常,可能不是在您的特定情况下),因此您可以让它们共享一个接口,该接口公开TableA 的集合属性,但您需要更高级别的上下文包装器来传递然后 - 除非您通过更改方法签名来传递集合。

    【讨论】:

      【解决方案2】:

      您可以使用接口。检查this answer,但请务必使用包含您拥有的表数量的 .tt 文件编写接口脚本。

      编辑:

      如果您已经生成了想要在可重用方法中互换使用的上下文,那么您会遇到生成的 TableA 类不可重用的问题,因为它们是不同的类型(即使名称可能匹配,但这并不使它们相等)。因此,您需要抽象实际类型,而做到这一点的一种方法是使用接口。您围绕抽象特定上下文类型和表类型的接口构建可重用方法。缺点是您必须在生成的上下文和表类型上实现接口。不过,您可以使用 .tt 脚本解决此问题。

      伪代码:

      // Define interface for table
      public interface ITableA {
          // ... properties
      }
      
      // Define interface for context
      public interface IMyContext {
          IQueryable<ITableA> TableA { get; }
      }
      
      // Extend TableA from DUK1
      public partial class TableA: ITableA {  
      }
      
      // Extend DUK1
      public partial class Datacontext.DAL.DUK1: IMyContext {
          IQueryable<ITableA> IMyContext.TableA { 
              get { return TableA; }
          }
      }
      
      // Same for DUK3 and TableA FROM DUK3
      
      
      // Finally, your code
      Datacontext.DAL.DUK1 duk1sdi = new     Datacontext.DAL.DUK1(connectionString);
      Datacontext.DAL.DUK3 duk3sdi = new     Datacontext.DAL.DUK3(connectionString);
      
      string fromOne = runQuery(duk1sdi);
      string fromThree = runQuery(duk3sdi);
      
      public static string runQuery(IMyContext duk) { 
          // Note: method accepts interface, not specific context type
      
          var query = from result in duk.TableA
                      select result.Total;
      
          string returnString = query;
          return returnString;
      }
      

      【讨论】:

        【解决方案3】:

        如果数据库之间的架构相同,为什么要为所有数据库编写 dbml 脚本?只需创建一个带有关联类的上下文,并在实例化上下文时动态切换出连接字符串。

        var duk1sdi = new     Datacontext.DAL.DUK1(connectionString1);
        var duk3sdi = new     Datacontext.DAL.DUK1(connectionString2);
        

        【讨论】:

          【解决方案4】:

          谢谢,伙计们,我想我根据您的回答和 RTFM(Paulo Pialorsi 和 Marco Russo 在 Microsoft .NET Framework 4 中编程 Microsoft Linq)为我找到了最简单的解决方案

          通过这种方式,我不必使用大型 DBML 文件。很遗憾,因为我将不得不以这种方式创建数百个表,但我现在可以在连接字符串之间动态切换。

          首先我创建表结构。 (程序代码块外)

          [Table(Name = "TableA")]
          public class TableA
          {
          [Column] public int result;
          }
          

          然后我定义要使用的表:

          Table<TableA> TableA = dc.GetTable<TableA>();
          

          然后我可以从中查询:

          var query =
          from result in TableA
          select TableA.result;
          

          【讨论】:

            猜你喜欢
            • 2011-01-09
            • 1970-01-01
            • 2019-12-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-06-21
            相关资源
            最近更新 更多