C# 流畅的 NHibernate,使用接口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/672032/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 12:45:20  来源:igfitidea点击:

Fluent NHibernate, working with interfaces

c#nhibernateinterfacemappingfluent

提问by Charles Ouellet

I just switched to Fluent NHibernate and I've encountered an issue and did not find any information about it.

我刚刚切换到 Fluent NHibernate,但遇到了一个问题,但没有找到任何相关信息。

Here's the case :

这是这种情况:

public class Field : DomainObject, IField
{
    public Field()
    {  
    }

    public virtual string Name { get; set; }
    public virtual string ContactPerson { get; set; }
    public virtual bool Private { get; set; }
    public virtual IAddress Address { get; set; }  
}

IAddress is an interface implemented by a class named Address

IAddress 是由名为 Address 的类实现的接口

public class Address : DomainObject, IAddress
{
    public Address()
    {
    }

    public virtual string City { get; set; }
    public virtual string Country { get; set; }
    public virtual string PostalCode { get; set; }
    public virtual string StreetAddress { get; set; }
}

Here's my mapping files for both classes

这是我的两个类的映射文件

ADDRESS

地址

public class AddressMap : ClassMap<Address>
{   
    public AddressMap()
    {
        WithTable("Addresses");
        Id(x => x.Id, "Id").Access.AsCamelCaseField(Prefix.Underscore).GeneratedBy.Guid();
        Map(x => x.City, "City");
        Map(x => x.Country, "Country");
        Map(x => x.PostalCode, "PostalCode");
        Map(x => x.StreetAddress, "StreetAddress");
    }
}

FIELD

场地

public class FieldMap : ClassMap<Field>
{
    public FieldMap()
    {
        WithTable("Fields");
        Id(x => x.Id, "Id").Access.AsCamelCaseField(Prefix.Underscore).GeneratedBy.Guid();
        Map(x => x.Name, "Name");
        Map(x => x.ContactPerson, "ContactPerson");
        Map(x => x.Private, "Private");
        References(x => x.Address, "AddressId").Cascade.Delete().Cascade.SaveUpdate();
    }
}

So when I tried to retrive a field object from my database, I get an NHibernate error that states that IAddress is not mapped. Is there any way to specify to NHibernate to use the Address class in the mapping?

因此,当我尝试从我的数据库中检索字段对象时,我收到一个 NHibernate 错误,指出 IAddress 未映射。有什么方法可以指定 NHibernate 在映射中使用 Address 类?

Please let me know if more information are needed.

如果需要更多信息,请告诉我。

Thanks a lot,

非常感谢,

Charles

查尔斯

采纳答案by cbp

I find that there are valid reasons for using an interface instead of a concrete class as a property.

我发现使用接口而不是具体类作为属性是有正当理由的。

For example, if your Field class was in a seperate project to the Address class, and you didn't have a dependency on the Address class's project from the Field class's project.

例如,如果您的 Field 类与 Address 类在一个单独的项目中,并且您没有从 Field 类的项目对 Address 类的项目的依赖。

There are other ways of dealing with this situation, but the simplest way is often to attempt what you are doing and explicity tell NHibernate the concrete class to use for IAddress.

还有其他方法可以处理这种情况,但最简单的方法通常是尝试您正在执行的操作并明确告诉 NHibernate 用于 IAddress 的具体类。

You can now do this in Fluent NHibernate, like this:

您现在可以在 Fluent NHibernate 中执行此操作,如下所示:

References(x => x.Address, "AddressId")
    .Class(typeof(Address);

Unfortunately you can't do this with HasMany or HasManyToMany. I'm not sure if this would even be possible due to lack of good covariance support in C#.

不幸的是,你不能用 HasMany 或 HasManyToMany 来做到这一点。由于 C# 中缺乏良好的协方差支持,我不确定这是否可能。

回答by Luke

On your Field object, you have an object of type IAddress. This could be implemented by any number of different implementations. With what you are asking, each implementation would have its own mapping, which would introduce any number of difficulties (impossibilities?) for NHibernate to handle.

在您的 Field 对象上,您有一个 IAddress 类型的对象。这可以通过任意数量的不同实现来实现。根据您的要求,每个实现都有自己的映射,这会给 NHibernate 带来许多困难(不可能?)。

A simple example would help to demonstrate. Say you have two IAddress implementations Address1, and Address2. They each are saved in their own table, tblAddress1, and tblAddress2. When you try to load your Field object, all NHibernate knows is that you have something that implements IAddress, it does not know which implementation was persisted. How would it know which mapping to use to retrieve the child object for any given field?

一个简单的例子将有助于演示。假设您有两个 IAddress 实现 Address1 和 Address2。它们都保存在自己的表 tblAddress1 和 tblAddress2 中。当你尝试加载你的 Field 对象时,NHibernate 只知道你有一些实现 IAddress 的东西,它不知道哪个实现被持久化。它如何知道使用哪个映射来检索任何给定字段的子对象?

I'm sure there are more complications, but this example shows why you have to have a mapping for the exact type of object that you have declared.

我确信还有更多的复杂性,但这个例子说明了为什么你必须为你声明的对象的确切类型建立一个映射。

回答by Stumblor

If you are interested in decoupling your ORM entirely from your domain layer, and referencing interfaces throughout your data layer rather than specifying concrete classes, you can implement an EmptyInterceptor to map between the two.

如果您有兴趣将 ORM 完全与域层解耦,并在整个数据层引用接口而不是指定具体类,则可以实现 EmptyInterceptor 以在两者之间进行映射。

See my answer here.

在这里看到我的答案。