我在C#ORM库中常见的惰性,急切和显式加载设计模式方面遇到了问题,特别是对于拥有自己的集合的派生类型。
例如,我想坚持下面的模型:
public abstract class Offer
{
public int Id { get; set; }
}
public class DiscountOffer : Offer
{
public float Percent { get; set; }
}
public class ColourOffer : Offer
{
public List<string> Colours { get; set; }
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; } = "Unknown";
public IList<Offer> Offers { get; set; } = new List<Offer>();
}
我可以使用Entity Framework或NHibernate轻松映射并将其保存到数据库中,当我想要从数据库中检索完整产品并使用WCF通过线路发送时,就会出现问题。
如果我有以下产品:
new Product
{
Name = "Chair",
Offers = new List<Offer>
{
new DiscountOffer { Percent = 0.2f },
new ColourOffer
{
Colours = new List<string>
{
"Red", "Blue", "Green"
}
},
}
};
如果产品是延迟加载的,那么它将封装在代理中,以便它知道何时获取子集合。这会出现问题,因为序列化将失败,因为类型不符合预期。
我找到了一些问题的答案:
Include
/ Fetch
ColourOffer.Colours
路径的方法:NHibernate的:
session.Get<Product>(1).Fetch(p => p.Offers) // If ColourOffer Fetch Colours?
EF:
DbSet<Product> Products { get; set; }
// ...
Products.Include(p => p.Offers) // If ColourOffer Include Colours?
使用DTO和AutoMapper。我已经收集了这个通常是一个好主意,但我遇到了同样的问题,不知道如何处理代理类,所以我必须禁用延迟加载,这让我回到第1点。
使用IDataContractSurrogate
在序列化中加载内容。我尝试了几种在网络上浮动的实现,但我无法工作。我相信这是因为会话被序列化关闭了,因此无法获取集合的数据。
我现在不知道该怎么办。我只想加载一个完整的产品,但我找不到解决方案,这让我疯了。
答案 0 :(得分:0)
使用Fluent NHibernate,添加DefaultLazy.Never()
约定似乎会导致在请求时获取完整的对象图。
Fluently.Configure()
// ...
.Mappings(m => m
.FluentMappings.AddFromAssemblyOf<MyClass>()
.Conventions.Add(FluentNHibernate.Conventions.Helpers.DefaultLazy.Never()))
// ...
这也有额外的好处,我没有必要处理不使用WCF的代理。