我已经开始在一个(有点像 DDD 的)系统中使用 Linq to SQL,它看起来(过于简化)如下所示:
public class SomeEntity // Imagine this is a fully mapped linq2sql class.
{
public Guid SomeEntityId { get; set; }
public AnotherEntity Relation { get; set; }
}
public class AnotherEntity // Imagine this is a fully mapped linq2sql class.
{
public Guid AnotherEntityId { get; set; }
}
public interface IRepository<TId, TEntity>
{
Entity Get(TId id);
}
public class SomeEntityRepository : IRepository<Guid, SomeEntity>
{
public SomeEntity Get(Guid id)
{
SomeEntity someEntity = null;
using (DataContext context = new DataContext())
{
someEntity = (
from e in context.SomeEntity
where e.SomeEntityId == id
select e).SingleOrDefault<SomeEntity>();
}
return someEntity;
}
}
现在,我遇到了一个问题。当我尝试像这样使用 SomeEntityRepository
public static class Program
{
public static void Main(string[] args)
{
IRepository<Guid, SomeEntity> someEntityRepository = new SomeEntityRepository();
SomeEntity someEntity = someEntityRepository.Get(new Guid("98011F24-6A3D-4f42-8567-4BEF07117F59"));
Console.WriteLine(someEntity.SomeEntityId);
Console.WriteLine(someEntity.Relation.AnotherEntityId);
}
}
一切正常,直到程序到达最后一个 WriteLine,因为它抛出一个ObjectDisposedException
,因为 DataContext 不再存在。
我确实看到了实际问题,但是我该如何解决呢?我想有几种解决方案,但迄今为止我所想到的没有一个适合我的情况。
- 摆脱存储库模式,并为工作的每个原子部分使用新的 DataContext。
- 我真的不想这样做。一个原因是我不想让应用程序知道存储库。另一个是我不认为让 linq2sql 的东西 COM 可见会很好。
- 另外,我认为这样做
context.SubmitChanges()
可能会比我预期的要多得多。
- 指定 DataLoadOptions 以获取相关元素。
- 因为我希望我的业务逻辑层在某些情况下只回复一些实体,所以我不知道他们需要使用哪些子属性。
- 禁用所有属性的延迟加载/延迟加载。
- 不是一个选择,因为有很多表,而且它们的链接很紧密。这可能会导致大量不必要的流量和数据库负载。
- 互联网上的一些帖子说使用 .Single() 应该会有所帮助。
- 显然它不...
有什么办法可以解决这个痛苦吗?
顺便说一句:我们决定使用 Linq t0 SQL,因为它是一个相对轻量级的 ORM 解决方案,并且包含在 .NET 框架和 Visual Studio 中。如果 .NET 实体框架更适合这种模式,则可以选择切换到它。(我们在实施方面还没有那么远。)