有没有办法在运行时设置TableAttribute,或者在运行时进行LINQ类型切换?

时间:2012-02-08 13:21:16

标签: .net clr iqueryable devart

我这样问了这个问题,因为我可以想象这是一个可能很容易但Devart特定的解决方案,但对于任何类似情况来说也许是一个非常通用的解决方案。

我使用Devart LINQ To Oracle,通常在设计时在lqml文件中创建类似ItemX的类,并指定它背后的表。然后,在运行时,使用Table(Of ItemX)来查询数据库。到目前为止一切都很好。

现在我遇到了两个相同的表ItemXItemY的情况,我需要根据运行时标志从一个或另一个查询。除此之外,所有代码都是相同的,我想保持这种方式。但是,Table(Of ItemX)是强类型的,因此我需要拥有所有内容的重复版本,唯一的区别是数据类型。

因此,Devart特定的解决方案是:只有一个项类叫做Item,但是在运行时做一些事情,以便Devart DataContext使用不同的支持表。然后,所有代码都使用基本Item对象,但是当持久进出数据库时,它知道要使用哪个表。有没有办法做到这一点?

更通用的方法是将某些方法连接到IQueryable链,以便它在内部使用ItemXItemY类,但将所有内容转换为基类Item类。外部签名。我甚至无法清楚地想象出这个问题。有没有办法实现这个目标?

1 个答案:

答案 0 :(得分:0)

您可以通过手动创建基类(未映射到任何表)和两个“平凡”后代(每个映射到您使用的其中一个表)来实现此方案。

更准确地说,应该执行以下步骤:

  • 生成一个模型,其实体类对应于任一表;
  • 将此实体类从生成的代码中移动到其他位置;
  • 从此类中删除Table属性;
  • (可选)将类重命名为例如'ItemBase';
  • 声明此类的两个公共后代(例如,'ItemX'和'ItemY');
  • 将Table属性设置为指向每个后代的正确表格;
  • 删除DataContext类的'ItemBases'属性(返回Devart.Data.Linq.Table对象;当然,它可能有其他名称),并添加返回Table和Table的类似属性。

因此,这看起来应该是

namespace MyContext {

  public partial class ItemBase : INotifyPropertyChanging, INotifyPropertyChanged {
    ... // Generated code.
  }

  [Table(Name = @"ItemXs")]
  public partial class ItemX : ItemBase {}

  [Table(Name = @"ItemYs")]
  public partial class ItemY : ItemBase {}

  public partial class MyDataContext {

    public Devart.Data.Linq.Table<ItemX > ItemXs {
      get { return this.GetTable<ItemX>(); }
    }

    public Devart.Data.Linq.Table<ItemY> ItemYs {
      get { return this.GetTable<ItemY>(); }
    }
  }

}