我有几个实体类用于解析固定宽度的文本文件以及利用Linq to SQL。我使用这些类来解析所述文本文件中的数据,并与数据库中的数据进行比较。
其中一个实体有很多属性,我不想浪费时间在Linq结果对象上设置每个单独的属性。
有没有办法告诉Linq“这是我的对象,用这个来更新记录”?这是我正在处理的代码:
if (partialContent.MonthlyAddChange == "A") { bookContentTable.InsertOnSubmit(partialContent); } else if (partialContent.MonthlyAddChange == "C") { var query = from bookContent in bookContentTable where bookContent.EAN == partialContent.EAN select bookContent; if (query != null) { // Do something with query.First() } } }
在这种情况下删除记录并执行InsertOnSubmit()是否更好?
答案 0 :(得分:2)
我认为编辑记录的概念与删除和插入新概念不同。基本上,我认为ORM应该抽象掉主键生成和其他相关的东西。通过删除和插入,您可能会删除记录的完整性(可能会发出新的主键,使引用的实体无效,等等......)。我建议每当你采取的行动概念上是更新时更新记录。
答案 1 :(得分:1)
我认为您可以使用类似DataContext.Table.Attach(record,true)和DataContext.SubmitChanges()之类的东西。但我没有把它完全充实......
所以现在我做了一个测试。这只有在您不需要并发检查时才会起作用(即您是唯一更新表的人)。
这是我的表
People
PersonID int
FirstName varchar(50)
LastName varchar(50)
我用以下记录填充了表格
> PersonID FirstName LastName
> 1 Jason Punyon
我创建了一个名为PeopleDataContext的LINQ2SQL DataContext,并且在People类的每个属性上,我将每个记录属性的UpdateCheck属性设置为Never。
以下是代码:
static void Main(string[] args)
{
var p = new People();
p.PersonID = 1;
p.FirstName = "Jason";
p.LastName = "This is a new last name";
using (var db = new PeopleDataContext())
{
db.Peoples.Attach(p, true);
db.SubmitChanges();
}
}
它成功运作。没有反思或任何东西,但就像我说的,你失去了并发检查。
答案 2 :(得分:1)
您可以考虑使用automapper为您复制值。请查看此信息以获取更多信息:http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/01/22/automapper-the-object-object-mapper.aspx
答案 3 :(得分:1)
在这种情况下删除记录并执行InsertOnSubmit()是否更好?
不,绝对不是 - 只考虑任何优秀,稳定的数据库设计应该使用的参照完整性。如果您的记录已被其他行使用,则不能简单地将其删除并重新插入 - 您将破坏这些完整性约束。
如果您只是更改了一些值,请更新现有行 - 更容易,更一致。
马克
答案 4 :(得分:0)
我不会删除/重新创建。假设两个对象具有相对于要更新的属性的相同接口,我将使用反射并将更改的值复制到现有对象。如果任何值与原始值不同,则记录将标记为需要更新,SubmitChanges将负责处理。
例如(几乎没有错误检查):
foreach (var bookInfo in bookContent.GetType().GetProperties())
{
var partialInfo = partialContent.GetType().GetProperty( bookInfo.Name );
if (partialInfo != null)
{
bookInfo.SetValue( partialInfo.GetValue( partialContent, null ) );
}
}
如果您知道它们属于同一类型,则可以重复使用第一个PropertyInfo,而不是为partialContent获取新的PropertyInfo。