简体   繁体   English

将int列表映射到nHibernate实体

[英]Mapping a List of ints to an nHibernate entity

So, I have an NHibernate entity which has an associated list, like so: 所以,我有一个NHibernate实体,它有一个相关的列表,如下所示:

public class CountSet{

    //Some other code here

    private readonly IList<int> _instanceCounts;

    public virtual IEnumerable<int> InstanceCounts
    {
        get { return _instanceCounts; }
        set
        {
            _instanceCounts.Clear();
            foreach (var instanceCount in value.Distinct())
            {
                _instanceCounts.Add(instanceCount);
            }
        }
    }  
}

And am mapping the entity with Fluent NHibernate, using automapping, but with an override to map the list, like so: 我正在使用Fluent NHibernate映射实体,使用自动化,但使用覆盖来映射列表,如下所示:

mapping.HasMany(x => x.InstanceCounts) 
            .Table(@"CountSetsInstanceCounts")
            .KeyColumn(@"InstanceCountSetId")
            .Element(@"InstanceCount");

This seems to be correctly creating the hbm xml, which looks like this: 这似乎是正确创建hbm xml,如下所示:

<bag table="CountSetsInstanceCounts" name="InstanceCounts" 
   access="field.camelcase-underscore" inverse="true" 
   cascade="all-delete-orphan">
    <key>
        <column name="InstanceCountSetId"/>
    </key>
    <element type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, ">
        <column name="InstanceCount"/>
    </element>
</bag>

Which looks correct to me. 这对我来说是正确的。 However, when I try and persist these entities to the database, the entity is saved correctly, but the collections are not. 但是,当我尝试将这些实体持久保存到数据库时,实体会正确保存,但集合不是。

Any suggestions as to what might be happening? 有关可能发生的事情的任何建议吗? Feel free to ask for more information. 随意询问更多信息。

You are almost there. 你快到了。 Your mapping is correct, and C# entities as well. 您的映射是正确的,也是C#实体。 The point is, that int cannot be managed via "inverse" setting, because it is not an entity. 关键是, int不能通过“反向”设置进行管理,因为它不是实体。 It must be set to inverse="false" . 它必须设置为inverse="false"

Adjust your mapping this way: 以这种方式调整映射:

mapping.HasMany(x => x.InstanceCounts) 
   .Table(@"CountSetsInstanceCounts")
   .KeyColumn(@"InstanceCountSetId")
   .Element(@"InstanceCount")
   .Not.Inverse()
;

This is basically because of your custom setter which uses a backing field. 这基本上是因为您的自定义setter使用了支持字段。 Therefore nhibernate does not have a reference object to track changes against. 因此,nhibernate没有用于跟踪更改的引用对象。

You have some options to fix it 你有一些选择来解决它

a) Remove the custom logic and simply use a)删除自定义逻辑并简单地使用

public virtual IEnumerable<int> InstanceCounts
{
    get;
    set;
}

This should work with your current mapping because nh can track changes of the auto property. 这应该适用于您当前的映射,因为nh可以跟踪auto属性的更改。

b) Change your mapping to specify the Access: .Access.CamelCaseField() To make this working, you also have to change the name of your backing field to not start with underscore. b)更改映射以指定Access: .Access.CamelCaseField()为了使其正常工作,您还必须将备份字段的名称更改为不以下划线开头。

As a side note: You defined the backing field as read-only. 作为旁注:您将支持字段定义为只读。 This doesn't really make sense if you expose the setter of your property. 如果您公开您的属性的setter,这没有任何意义。

If you want to have read-only property, remove the setter and maybe implement a method to set the list of values. 如果您想拥有只读属性,请删除setter并实现一个方法来设置值列表。 Or, if you don't need the read-only flag and still want to have the backing field, change your code to 或者,如果您不需要只读标志但仍希望拥有支持字段,请将代码更改为

public virtual IEnumerable<int> InstanceCounts
{
    get { return instanceCounts; }
    set { instanceCounts = value.ToList(); }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM