c#Linq to Sql动态数据上下文赋值

时间:2013-07-22 14:25:33

标签: c# linq-to-sql

`您好,

有人可以给我一个指针吗?我有8个服务器,每个服务器有8个数据库,看起来相同exept服务器/数据库名称我们正在谈论数以千计的表格。

我使用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时运行查询没有问题,但是如何定义datacontext并将其传递给函数?

我得到的错误是:

  

错误1'System.Data.Linq.DataContext'不包含定义   'TableA'并没有扩展方法'TableA'接受第一个   可以找到类型'System.Data.Linq.DataContext'的参数(是   你错过了使用指令或程序集引用?)

4 个答案:

答案 0 :(得分:1)

您可以使用界面。检查this answer,但一定要使用.tt文件编写接口脚本,并附上您拥有的表。

编辑:

如果您已生成要在可重用方法中互换使用的上下文,则会遇到生成的TableA类不可重用的问题,因为它们是不同的类型(即使名称可能匹配,但不是; t使它们相等)。因此,您需要抽象实际类型,一种方法是使用接口。您可以围绕特定上下文类型和表类型的接口构建可重用的方法。缺点是您必须在生成的上下文和表类型上实现接口。这可以通过.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;
}

答案 1 :(得分: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 :(得分:0)

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

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

答案 3 :(得分:0)

谢谢,伙计们,我认为我根据你的答案和RTFM(由Paul 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;