C# 使用LINQ到SQL在数据库之间进行复制
给定两个模式相同的数据库,有没有简单的方法在这两个数据库之间传输记录?我正在使用LINQtoSQL,因为我需要在此过程中执行一些额外的操作,而使用表示我正在传输的记录的对象使这变得更容易。这是一个小规模的助手应用程序,所以SSIS可能有些过分,SQLBulkCopy不允许我在途中轻松地查询对象 我想做的是:C# 使用LINQ到SQL在数据库之间进行复制,c#,linq-to-sql,C#,Linq To Sql,给定两个模式相同的数据库,有没有简单的方法在这两个数据库之间传输记录?我正在使用LINQtoSQL,因为我需要在此过程中执行一些额外的操作,而使用表示我正在传输的记录的对象使这变得更容易。这是一个小规模的助手应用程序,所以SSIS可能有些过分,SQLBulkCopy不允许我在途中轻松地查询对象 我想做的是: public static void TransferCustomer (DBDataContext DCSource,
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...
};
}
然后插入克隆项。如果我只复制有问题的字段,而不复制任何表示表关系的引用,这就可以了。不过,这有点冗长,我的做法需要手动分配克隆方法中的每个字段。有人能提出一些方法让这更容易吗?我想知道的两件事是:
非常感谢 这纯粹是一项学术活动吗
如果不是的话,我会认真考虑使用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?我在文档中找不到任何参考资料……是的——谷歌只找到了一个结果:这个页面!