C# LINQ to SQL - 动态选择表

7
我有以下场景:有一个数据库,每年都会生成一个新的logTable。它从2001年开始,现在已经有11个表。它们都具有相同的结构,因此具有相同的字段、索引、主键等。
我有一些称为“managers”的类,正如其名称所示,它们管理这个数据库上的每个操作。对于每个不同的表,我都有一个manager,除了这个logTable,我只有一个manager。
我阅读了很多资料并尝试了不同的方法,比如使用ITable来动态获取表或者一个所有表都实现的接口。不幸的是,我失去了强类型属性,因此我不能进行任何搜索、更新或其他任何操作,因为我不能使用logTable.Where(q=> q.ID == paramId)
考虑到这些表具有相同的结构,查询2010年的日志的查询可能是与查询2011年及以后的日志完全相同的。
我之所以问这个问题,是因为我不想为每个表重写相同的代码,因为它们在结构上是相同的。
编辑
我使用Linq to SQL作为我的ORM。这些表使用所有的DB操作,而不仅仅是选择。

表格的命名方式是怎样的?(例如:Log_2011,Log_2010) - as-cii
@AS-CII 是的,就像那样(Log_2009,Log_2010,Log_2011等等) - AdrianoRR
3个回答

2
考虑将所有日志放在一个表中,并使用分区来维护性能。如果不可行,您可以创建一个视图,将所有日志表合并在一起,并在选择日志数据时使用该视图。这样,当您添加新的日志表时,只需更新视图以包括新表。
编辑最近的评论:
听起来你需要一个新的DBA,如果他不让你创建新的SPs。是的,我认为你可以定义一个ILogTable接口,然后使你的日志表类实现它,但这不允许你做GetTable<ILogTable>()。你必须有某种DAL类,其中有一个创建联合查询的方法,例如:
public IEnumerable<ILogTable> GetLogs()
{
    var Log2010 = from log in DBContext.2010Logs
                  select (ILogTable)log;
    var Log2011 = from log in DBContext.2011Logs
                  select (ILogTable)log;
    return Log2010.Concat(Log2011);
}

上述代码完全未经测试,可能会出现严重故障;-)
编辑以让@AS-CII满意;-)

很不幸,我不是DBA,没有经过他的咨询我不能做出任何更改。我喜欢视图的想法。你能给我提供一个简单的例子吗?我尝试创建一个接口,让所有我的日志视图都继承它,但即使这样也没有成功。 - AdrianoRR
如果您的数据库管理员按照描述创建了视图,那么您只需从VS中的服务器资源管理器窗口将其拖入设计器窗口中,适当的类型就会被创建。简单吧 ;-) - Ben Robinson
不,您不能向视图中插入数据。但是,您可以拥有存储过程,从正确的表中插入/更新/删除。您可以将 SP 调用连接到数据上下文上的添加/删除/更新事件,以使此过程透明化。 - Ben Robinson
是的,当你使用“视图”这个术语时,我感到困惑了,因为我正在使用asp.net mvc3。我知道视图只是预定义选择的结果。但是,我也不能使用SP。这是我无法跨越的规则。难道没有办法使用ITable接口或创建一个所有表都继承的类,然后创建一个方法来返回此基类吗?上次我尝试使用GetTable<T>().Where(q => q.ID == logId);来实现它,但我得到了一个运行时异常,说我的基类未映射为表。 - AdrianoRR
@Ben,+1。现在我真的很开心。 :) - as-cii
显示剩余6条评论

1
你可能想看看Codeplex Fluent Linq to SQL项目。虽然我没用过它,但我从使用 EF4 中类似的映射技术中熟悉这些思路。你可以创建一个单一的对象并使用诸如以下语法动态地将其映射到不同的表:
public class LogMapping : Mapping<Log> {
    public LogMapping(int year) {
        Named("Logs" + year);
        //Column mappings...
    }
}

该项目自2008年以来就没有更新过,也不再处于活跃开发阶段。虽然从理论上看很不错。 - Ben Robinson
2
@Ben,同样也可以这样说Winforms和LINQ to SQL。如果技术已经成熟,就可能不需要进行积极的开发。 - Jim Wooley
@Steve,使用这个流畅的Linq to Sql,我能够映射日志表结构,以便在任何类或方法中使用它吗?就是这样吗?如果是的话,那就解决了我的问题。 - AdrianoRR
理论上是可以的。就像我说的,我从未使用过它,但使用流畅的EF4,它确实可以这样工作。 - Steve Danner
+1:我需要在一个传统的LINQ to SQL应用程序中添加动态映射,这似乎非常完美,谢谢。 - rsenna

0

是的,我在想是否应该采用ExecuteQuery的方式。然而,LINQ的建议不是使用直接的SQL查询吗?我认为这有点偏离正道。尽管如此,由于没有直接的输入可以注入我的代码,我可能最终会使用它。 - AdrianoRR
真的,ExecuteQuery并不像LINQ那样灵活,但有时你必须做你必须做的事情。如果你想更加动态化,考虑阅读以下文章:http://weblogs.asp.net/davidfowler/archive/2010/08/02/introduction-to-microsoft-data-dll.aspx - Jim Wooley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接