C# 使用LINQ到SQL在数据库之间进行复制

C# 使用LINQ到SQL在数据库之间进行复制,c#,linq-to-sql,C#,Linq To Sql,给定两个模式相同的数据库,有没有简单的方法在这两个数据库之间传输记录?我正在使用LINQtoSQL,因为我需要在此过程中执行一些额外的操作,而使用表示我正在传输的记录的对象使这变得更容易。这是一个小规模的助手应用程序,所以SSIS可能有些过分,SQLBulkCopy不允许我在途中轻松地查询对象 我想做的是: public static void TransferCustomer (DBDataContext DCSource,

给定两个模式相同的数据库,有没有简单的方法在这两个数据库之间传输记录?我正在使用LINQtoSQL,因为我需要在此过程中执行一些额外的操作,而使用表示我正在传输的记录的对象使这变得更容易。这是一个小规模的助手应用程序,所以SSIS可能有些过分,SQLBulkCopy不允许我在途中轻松地查询对象

我想做的是:

public static void TransferCustomer
                     (DBDataContext DCSource, 
                      DBDataContext DCDest, 
                      int CustomerID)
{
  Customer customer;
  using (DCSource = new DBDataContext(SourceConnStr))
  {
    customer = DCSource.Customers
                       .Where(c => c.CustomerID == CustomerID)
                       .Single();
  }

  using (DCDest = new DBDataContext(DestConnStr))
  {
    DCDest.Customers.InsertOnSubmit(customer);
    DCDest.SubmitChanges();
  }
}
但出于显而易见的原因,这会引发消息异常:

已尝试附加或添加非新实体,可能是从另一个DataContext加载的。这是不受支持的

我可以通过这样做对象的浅拷贝来解决这个问题:

public static Customer Clone(this Customer customer)
{
  return new Customer()
  {
    Name = customer.Name,
    Email = customer.Email
    etc...
  };
}
然后插入克隆项。如果我只复制有问题的字段,而不复制任何表示表关系的引用,这就可以了。不过,这有点冗长,我的做法需要手动分配克隆方法中的每个字段。有人能提出一些方法让这更容易吗?我想知道的两件事是:

  • LINQ到SQL能否以更简单的方式实现这一点
  • 有没有一种很好的方法可以使用反射来制作一个浅拷贝,它将插入

  • 非常感谢

    这纯粹是一项学术活动吗


    如果不是的话,我会认真考虑使用SSIS:替代,或者不使用Rhino ETL:在数据库之间传输数据。[link text][1]

    以下是一种浅层克隆LINQ对象的方法(省略主键):

    如果不使用属性,可以调整它以使用元模型。然后您只需要2个数据上下文(一个源,一个目标)


    或者,您可以查看
    SqlBulkCopy
    ——请参见为什么要使用LINQ来执行此操作?当您可以使用SQL Server的DTS时,框架似乎有点浪费。我使用DataContractCloner将LINQ分离为SQL实体:

    /// <summary>
    /// Serializes the entity to XML.
    /// </summary>
    /// <returns>String containing serialized entity.</returns>
    public string Serialize()
    {
        return DataContractCloner.Serialize<Organization>(this);
    }
    
    /// <summary>
    /// Deserializes the entity from XML.
    /// </summary>
    /// <param name="xml">Serialized entity.</param>
    /// <returns>Deserialized entity.</returns>
    public static Organization Deserialize(string xml)
    {
        return DataContractCloner.Deserialize<Organization>(xml);
    }
    
    //
    ///将实体序列化为XML。
    /// 
    ///包含序列化实体的字符串。
    公共字符串序列化()
    {
    返回DataContractCloner.Serialize(此);
    }
    /// 
    ///从XML反序列化实体。
    /// 
    ///序列化实体。
    ///反序列化实体。
    公共静态组织反序列化(字符串xml)
    {
    返回DataContractCloner.Deserialize(xml);
    }
    

    所有LINQ到SQL实体都已注释,因此这将创建一个可附加的克隆,您可以稍后重新附加该克隆,但需要注意一些事项。首先,将解析外键关系,因此必须按依赖关系的顺序插入,如果有循环关系,则必须从模式中删除外键,并在传输后重新应用。其次,LINQtoSQL不执行标识插入,所以如果您使用的是自动增量标识列,那么在提交时就会出现问题。我还没有成功地强制DATACONTRONT启用身份插入,但是YMMV.

    < P>您可能会考虑使用Sql BulkCopyC类。您可以在此处找到关于它的代码项目文章:。这将是一种更快的方法,但我想这将需要您自己创建查询,而不是让LINQ to SQL来创建查询。

    试试这个

    using (DCDest = new DBDataContext(DestConnStr))
    {
        DCDest.Customers.InsertOnSubmit(customer.ToList());  //note the use of .ToList()
        DCDest.SubmitChanges();
    }
    

    这是真实的,但对我来说只是一个轻量级的助手应用。我预计在每个批处理中,跨多个表传输的行不会超过50行,因此我认为SSIS可能有些过头了。我目前的解决方案是对每个对象使用克隆方法,效果非常好,但感觉不雅。我需要添加更多的表,所以我想在编写更多克隆方法之前找到更好的方法!你甚至不需要DTS;SqlBulkCopy可以工作,大约需要5行代码。我需要能够在此过程中执行一些额外的操作-在这种情况下,拥有实体类可以在其他方面让我的生活更轻松。。。我知道这不是传输记录的最佳方式,但还有一些其他因素使我想使用LINQ。我认为您可以使用DTS进行定制。我不太确定它有多灵活。如果您在这里找不到答案,我认为值得调查。@Marc,我知道SqlBulkCopy,但这会比DTS甚至BCP输出再输入快吗?这真的很有帮助,谢谢。我使用的是自动生成的实体类,因此它们具有使用克隆方法所需的所有标记。我仍然觉得LINQ to SQL应该让这变得更容易,但如果没有人知道怎么做,这将节省我很多时间。也许是个愚蠢的问题,但什么是DataContractCloner?我在文档中找不到任何参考资料……是的——谷歌只找到了一个结果:这个页面!