请考虑以下情况......
我有对象来定义不同类型的产品以及描述该产品所需的属性(例如电视与香水具有不同的属性等)。
因此,我有ProductType
的概念,其List<>
属性包含不同字段(AttributeField<T>
)的元素。
AttributeField<T>
针对不同的值(List<>
)具有AttributeValue<T>
属性。
然后,产品会有ProductType
来定义此特定产品的值的可用字段(AttributeField<T>
)和List<AttributeValue<?>>
。
我试图在C#中实现这个概念。我有为接口和对象定义的结构,但我正在努力使用Fluent NHibernate映射对象,可能是因为ProductType
不是泛型类但具有泛型属性(List<AttributeField<T>>
其中T可以是任何东西)。
接口&gt; IProductType
public interface IProductType
{
Guid Id { get; set; }
string Name { get; set; }
List<IAttributeField> Fields { get; set; }
}
接口&gt; IAttributeField / IAttributeField
public interface IAttributeField
{
Guid Id { get; set; }
string Name { get; set; }
IProductType ProductType { get; set; }
}
public interface IAttributeField<T> : IAttributeField
{
Guid Id { get; set; }
string Name { get; set; }
List<IAttributeValue<T>> Values { get; set; }
IProductType ProductType { get; set; }
}
接口&gt; IAttributeValue
public interface IAttributeValue<T>
{
Guid Id { get; set; }
T Value { get; set; }
IAttributeField<T> Field { get; set; }
}
课程&gt; ProductType
public class ProductType : IProductType
{
public Guid Id { get; set; }
public string Name { get; set; }
public List<IAttributeField> Fields { get; set; }
}
课程&gt; AttributeField
public class AttributeField<T> : IAttributeField<T>
{
public Guid Id { get; set; }
public string Name { get; set; }
public List<IAttributeValue<T>> Values { get; set; }
public IProductType ProductType { get; set; }
}
课程&gt;的AttributeValue
public class AttributeValue<T> : IAttributeValue<T>
{
public Guid Id { get; set; }
public T Value { get; set; }
public IAttributeField<T> Field { get; set; }
}
我正在使用Fluent NHibernate for ORM和SQL 2008数据库并具有以下映射类:
课程&gt; ProductTypeMapping
public class ProductTypeMapping : ClassMap<IProductType>
{
public ProductTypeMapping()
{
Not.LazyLoad();
Id(x => x.Id).GeneratedBy.GuidNative();
Map(x => x.Name).Length(50).Not.Nullable();
HasMany(x => x.Fields).CollectionType<IAttributeField>();
}
}
课程&gt; AttributeFieldMapping
public class GenericAttributeFieldMapping : ClassMap<IAttributeField>
{
public GenericAttributeFieldMapping()
{
Not.LazyLoad();
Id(x => x.Id);
Map(x => x.Name).Length(50).Not.Nullable();
References(x => x.ProductType).Cascade.All();
}
}
public class AttributeFieldMapping<T> : ClassMap<IAttributeField<T>>
{
public AttributeFieldMapping()
{
Not.LazyLoad();
Id(x => x.Id).GeneratedBy.GuidNative();
Map(x => x.Name).Length(50).Not.Nullable();
HasMany(x => x.Values).Cascade.AllDeleteOrphan();
References(x => x.ProductType).Cascade.All();
}
}
课程&gt; AttributeValueMapping
public class AttributeValueMapping<T> : ClassMap<IAttributeValue<T>>
{
public AttributeValueMapping()
{
Not.LazyLoad();
Id(x => x.Id).GeneratedBy.GuidNative();
Map(x => x.Value).CustomType<T>();
References(x => x.Field).Cascade.All();
}
}
当我尝试使用new PersitenceSpecification<ProductType>
对上述单元进行单元测试时,出现以下错误:
单元测试适配器抛出异常: 成员'FluentNHibernate.Cfg.FluentConfigurationException,FluentNHibernate,Version = 1.3.0.733,Culture = neutral,PublicKeyToken = 8aa435e3cb308880'
的类型未解析进一步调试时,我收到以下异常消息:
没有持久性:System.Collections.Generic.List`1 [[Models.Interfaces.IAttributeField,Models,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]]
可能这是因为我不能使用泛型类型进行映射,需要为每个要映射的泛型类型提供映射。
如何让上面详述的结构与依赖注入和ORM一起工作,而不必为每个泛型类型显式提供映射或者可以对我使用ORM的方法进行哪些更改,同时仍然可以灵活地使模型具有不同的属性(字段和值)?
答案 0 :(得分:1)
Fluent NHibernate是一个对象关系映射器和持久性解决方案。它不是依赖注入容器。
通过数据库模式的可见性给出具体答案会容易得多。但是我知道这可能不实用。
听起来我正在尝试使用Fluent NHibernate创建应用程序对象,而不是仅仅依靠它来实现持久性。这可能会导致一些非常复杂的映射作为ORM的一部分,这可能会导致许多映射类。如此处所述,您需要为泛型中的每种具体类型设置一个映射类:Map generic EntityBase<TEntity> class with FluentNHibernate因此,我认为每个IAttributeField<T>
和每个IAttributeValue<T>
需要一个
我会尝试尽可能地简化映射类以匹配您的数据模型,并使用服务层与一些工厂或AutoMapper来构建您的应用程序对象。并不总是建议将持久化实体与应用程序分开(因为它可能会增加不必要的层次和复杂性 - 通心粉代码)但在这种情况下似乎可能是必要的。
正如我所说,从数据模型开始,向外工作最好,并确保您了解Fluent NHibernate只是一个具有许多强大功能的ORM