我一直在使用Linq to SQL来实现我一直在努力的新实现。我有大约5000行代码,并且从一个可靠的演示中获得了一些方法。到目前为止,我对Linq to SQL非常满意 - 这些工具非常棒且非常轻松,它可以让你快速启动并运行DAL。
那就是说,有一些主要的缺点,我只是一遍又一遍地打击。即如何处理我的DAL和我的业务层之间的关注点分离以及处理不同的数据上下文。
这是我一直使用的架构:我的存储库完成所有数据访问,并将Linq返回给SQL对象。我的每个Linq to SQL对象都实现了一个IDetachable接口。典型的实现如下所示:
partial class PaymentDetail : IDetachable
{
#region IDetachable Members
public bool IsAttached
{
get { return PropertyChanging != null; }
}
public void Detach()
{
if (IsAttached)
{
PropertyChanged = null;
PropertyChanging = null;
Transaction.Detach();
}
}
#endregion
}
每次我在我的存储库中执行DAL操作时,当我完成对象(理论上它应该与任何子对象分离)时,我“分离”以删除DataContext的上下文。
就像我说的,这很有效,但是有一些边缘情况似乎是屁股的巨大痛苦。例如,我的Transaction对象有很多PaymentDetails。即使该集合中有 no PaymentDetails,它仍然附加到DataContext的上下文中!因此,如果我尝试更新(我通过Attach()更新对象然后SubmitChanges())我得到了可怕的“已尝试附加或添加一个非新的实体,可能已从另一个DataContext。不支持。“消息。
无论如何,我开始怀疑这项技术是一场好赌博。有没有人有一个他们愿意分享的体面建筑?我真的很喜欢使用这项技术,但我觉得我花了1/3的时间来调试是迟钝的怪癖!
答案 0 :(得分:1)
DataContext的生命周期应该是“工作单元”的生命周期。
示例: 将资金从一个帐户转移到另一个帐户
这涉及原子事务中的两个步骤:
您的DataContext不应在第一步后自行分离。它应该保持活着,直到两个步骤都完成。
答案 1 :(得分:1)
我个人仅在所有CRUD方法的“使用”块中使用DataContext。
使用Detach()有一种更简单的方法。我只在保存实体时使用它,更新工作正常。关于如何“修复”你提到的可怕错误的在线文章很少,但根据我的经验,当DAL设计得当时你根本不需要这样做。
我还设置了延迟加载,以便它不加载任何相关数据,我一次只使用一个实体,即Order,Customer,Item。
当我保存多个项目的订单时,我简单地遍历Items并在每个item方法上调用.Save()。 Save方法根据对象的Id确定它是更新的还是插入的。
同时使用时间戳进行并发似乎比比较旧对象和新对象更容易,更有效。
答案 2 :(得分:0)
如果您正在寻找示例,请尝试StackOverflow!
要查看StackOverflow的LINQ To SQL模型,请查看this video from PDC 2008 at around 51:00。