【问题标题】:Can Linq-To-Sql be aware of similarities of two tables?Linq-To-Sql 可以知道两个表的相似之处吗?
【发布时间】:2009-10-07 17:32:48
【问题描述】:

假设我的数据库中有 2 个表,具有相同的架构(列、类型等)。 Linq-To-Sql 可以将它们视为Table<AClass> 对它们使用相同的类吗?怎么做?

【问题讨论】:

    标签: .net sql linq linq-to-sql


    【解决方案1】:

    UNION 和 CONCAT 运算符可以在不同的表中使用,就像在单个表中多次使用一样容易。 UNION 和 CONCAT 运算符的链接:http://blog.benhall.me.uk/2007/08/linq-to-sql-difference-between-concat.html

    如果您有细微的差异,您可以通过创建一个仅公开相同字段的包装对象来隐藏它们(并重命名任何不匹配的字段)。

    这是我使用两个不匹配的表创建的 LINQPAD 示例。它工作得很好(按预期合并我添加到第二个的假行):

    var set1 = from  t in TestTriggers
    select new {t.TestTriggerID} ;
    
    var set2 = from t in TestTrigger2s
    select new {t.TestTriggerID} ;
    
    set1.Dump();
    set2.Dump();
    
    set1.Union(set2).Dump();
    set1.Concat(set2).Dump();
    

    两个表都有其他列,但匿名类型隐藏了这些。结果:

    IOrderedQueryable<> (1 item)  
    TestTriggerID 
    1
    
    
    IOrderedQueryable<> (2 items)  
    TestTriggerID 
    1
    
    2
    
    
    IOrderedQueryable<> (2 items)  
    TestTriggerID 
    1
    
    2
    
    
    IOrderedQueryable<> (3 items)  
    TestTriggerID 
    1
    
    1
    
    2
    

    您可以看到 CONCAT 复制了两个表中的 1 行,而 UNION 丢弃了重复项。

    【讨论】:

      【解决方案2】:

      如果您在不同架构中有两个具有相同名称的表,您可以通过从 Table 属性中删除架构名称并使用不同的连接字符串重新创建 DataContext 来实现所需的行为。
      如果您在同一架构中有两个名称不同且结构相同的表,我们不知道有什么方法可以将这些表映射到单个类。

      【讨论】:

        【解决方案3】:

        如果仅用于查询,一种选择是在合并结果的服务器上创建一个视图。

        对于更新方案,您会遇到更多困难,因为 LINQ to SQL 无法知道要使用哪个表...

        【讨论】:

          【解决方案4】:

          Linq-To-Sql 是否可以使用相同的类将它们视为 Table?

          没有。在同一个 DBML 文件(同一个命名空间)上不能有两个同名的类。此外,LINQ-to-SQL 怎么知道要插入或更新哪个表?

          一个更好的问题是:如果您有两个具有相同架构的表,并且您想将它们作为一个集合一起使用,为什么不将它们合并为一个表?

          【讨论】:

          • @DamienG 是的,表名和类名可以不同,但​​这与我的答案有什么关系?
          【解决方案5】:

          阅读:没问题。查询可以投影为任意类型,LinqToSql 会将属性名称与列结果匹配。

          from c in dc.Customer
          where c.Address.StreetName.StartsWith("AB")
          select new Person() {Name = c.Name};
          

          一个(如上面的查询)在通过以下操作枚举时被解析:

          • 生成sql
          • DataContext.ExecuteQuery&lt;Person&gt;() 使用该 sql 字符串和参数 documetation 调用
            • 将 sql 发送到数据库并返回一个 datareader。
            • 数据读取器被传递给DataContext.Translate&lt;Person&gt;()docmentation

          在此查询的情况下 - 仅获取 Customer.Name 列,并且没有新的 Customer 实例。另请注意 - 如果您有数据阅读器,您可以自己致电 DataContext.Translate&lt;T&gt;

          如果您想添加一个类似于单一类型的可查询表的属性,请在您的部分 DataContext 文件中执行此操作:

          public IQueryable<CustomType> CustomTypeTable
          {
            get
            {
              var query = this.Type1Table.Select(t1 => new CustomType{f1 = t1.f1 ... })
                .Concat( this.Type2Table.Select(t2 => new CustomType{f1 => t2.f1 ... })
              return query
            }
          }
          

          对于写作... DataContext 中的 ObjectTracking 是按 Type 和 PrimaryKey。每个实例的类型都需要(明确地)映射到数据库中的表。因此,在这些情况下,您不能将 1 个类型映射到 2 个表。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-10-23
            • 1970-01-01
            • 2023-03-06
            • 1970-01-01
            • 2011-08-24
            • 2011-05-02
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多