FluentNHibernate:当许多是简单枚举时如何处理一对多值

发布于 2024-09-16 23:29:40 字数 545 浏览 4 评论 0原文

看起来以下情况应该并不罕见,但我不知道如何在 FluenNHibernate 中处理它:

public class Product: BaseEntity
{
    public Product()
    {
        Categories = new List<Category>();
    }

    public virtual IList<Category> Categories { get; set; }
    ...
}

public enum Categories
{
    Classic = 1,
    Modern = 2,
    Trendy = 3,
    ...
}

所以,我需要一个 ProductCategories 表,它允许我将一个产品映射到多个类别,但我不认为NHibernate 将处理这个问题,除非我有一个实际的类别类和一个指定了多对多关系的类别表。这样做不可取的原因有很多,其中最重要的是它太过分了。

我正在使用 AutoMapper - 有什么方法可以覆盖以使其工作吗?

谢谢!

It seems like the following scenario shouldn't be uncommon, but I can't figure out how to handle it in FluenNHibernate:

public class Product: BaseEntity
{
    public Product()
    {
        Categories = new List<Category>();
    }

    public virtual IList<Category> Categories { get; set; }
    ...
}

public enum Categories
{
    Classic = 1,
    Modern = 2,
    Trendy = 3,
    ...
}

So, I need a ProductCategories table that allows me to map one product to many categories, but I don't think NHibernate will handle this unless I have an actual Categories class and a Categories table with a many-to-many relationship specified. There are a number of reasons this is not desirable, not the least of which is that it's overkill.

I'm using AutoMapper - any way I can override to make this work?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

新雨望断虹 2024-09-23 23:29:40

这个接受的答案对我有用,但是枚举被映射为 int 。

为了将其映射为字符串(我的偏好),我调整了映射,如下所示:

public void Override(AutoMapping<Account> mapping)
{
    mapping
        .HasMany(x => x.Categories)
        .Table("CategoriesProductsMap")
        .Element("Category", e => e.Type<NHibernate.Type.EnumStringType<Category>>())
        .AsSet();
}

This accepted answer worked for me, however the enum was mapped as in int.

To get it to map as a string (my preference) I adapted the mapping as follows:

public void Override(AutoMapping<Account> mapping)
{
    mapping
        .HasMany(x => x.Categories)
        .Table("CategoriesProductsMap")
        .Element("Category", e => e.Type<NHibernate.Type.EnumStringType<Category>>())
        .AsSet();
}
心凉 2024-09-23 23:29:40

我曾在像这样的另一个实例中尝试过连接字符串,但我真的想要一些不需要每次都进行转换的东西。事实证明,我在这里发现了一个非常相似的问题: Map to a list of Enums? 。如那里所述,此覆盖有效:

public void Override(AutoMapping<Product> mapping)
{
     mapping.HasMany(x => x.Categories).KeyColumn("ProductFk").Table("CategoriesProductsMap").Element("Category").AsBag();
}

I had tried the concatenated string in another instance like this, but I really wanted something that didn't need to be transformed every time. As it turns out, I found a very similar question here: Map to a list of Enums?. As described there, this override works:

public void Override(AutoMapping<Product> mapping)
{
     mapping.HasMany(x => x.Categories).KeyColumn("ProductFk").Table("CategoriesProductsMap").Element("Category").AsBag();
}
静水深流 2024-09-23 23:29:40

有几种方法可以做到这一点,但没有一种方法像您想象的那么简单。虽然 NHibernate 和 Fluent NHibernate 在使用单个 enum 时表现得很好,但集合则明显更麻烦。

以下是几种方法:

  1. 通过连接成员将集合保留到单个 nvarchar(?) 列。
  2. 使用 Flags 属性标记 enum 并将列表折叠为位掩码(这将只需要一个整数列)

在任何一种情况下,您都可以让 NHibernate 访问包含以下内容的字段: “折叠”值;公共属性的 getter 会将折叠的值转换为集合。折叠值的 getter 会将集合转换为单个字符串 (1) 或整数 (2)。

您必须显式映射 Product

public class ProductMap : ClassMap<Product>
{
    public ProductMap()
    {
        Id(x => x.Id);

        Map(Reveal.Member<Product>("_categories"))
            .Access.Field();
    }
}

因此,尽管 Product 公开了 IList,NHibernate 只会获取和设置_categories 字段;

There are a few ways to do this, none of them as straightforward as you might expect. While NHibernate and Fluent NHibernate do quite well with a single enum, a collection is significantly more troublesom.

Here are a couple of approaches:

  1. Persist the collection to a single nvarchar(?) column by concatenating the members.
  2. Mark the enum with the Flags attribute and collapse the list as a bitmask (this will require just one integer column)

In either case, you can have NHibernate access a field that contains the "collapsed" values; the getters of the public properties will transform the collapsed values to collections. The getter of the collapsed value will transform the collection into a single string (1) or integer (2).

You'd have to map Product explicitly:

public class ProductMap : ClassMap<Product>
{
    public ProductMap()
    {
        Id(x => x.Id);

        Map(Reveal.Member<Product>("_categories"))
            .Access.Field();
    }
}

So although Product exposes an IList<Category>, NHibernate will only get and set the value of the _categories field;

为人所爱 2024-09-23 23:29:40

在工作中,虽然它不涉及枚举值的集合,但我们创建了一个自定义类型(通过实现 IUserType 来存储 IDictionary

我们将字典到 xml 文档 (XDocument),我们将数据存储在 Sql Server 中的 Xml 列中,尽管任何字符串列都可以存储该值

。 custom-types-in-nHibernate.aspx" rel="nofollow noreferrer">此站点 了解有关实现 IUserType 的信息。

At work, while it did not concern a collection of enum value, we created a custom type (by implementing IUserType to store a IDictionary<CultureInfo, string>.

We converted the dictionary into a xml document (XDocument) and we stored the data in an Xml column in Sql Server, although any string column could store the value.

You can see this site for information about implementing IUserType.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文