【问题标题】:NHibernate mapping for a readonly property using iterators (yield return)使用迭代器的只读属性的 NHibernate 映射(收益返回)
【发布时间】:2013-07-25 19:11:40
【问题描述】:

是否可以在 NHibernate 中映射一个使用迭代器的只读属性(即,yield return)?

例如,假设我们有一个 Person 类,该类具有一个只读的 IEnumerable<Cat> Cats 属性和一个名为 GetNextCat() 的方法,该方法可以获取序列中的下一只猫。

这是可能的映射:

public class PersonMap : ClassMap<Person>
{
    public PersonMap()
    {
        HasMany(x => x.Cats).Access.ReadOnly(); // also tried .AsSet() and .AsBag()
    }
}

下面是IEnumerable&lt;Cat&gt; Cats 属性的两种可能实现:

// fails: 
//   System.InvalidCastException: Unable to cast object of type '<get_Cats>d__0' to 
//   type 'System.Collections.Generic.ICollection`1[MyProject.Cat]'.
public virtual IEnumerable<Cat> Cats
{
    get
    {
        var cat = GetNextCat();

        while(cat != null)
        {
            yield return cat;
            cat = GetNextCat();
        }

        yield break;
    }
}

// works
public virtual IEnumerable<Cat> Cats
{
    get
    {
        var catList = new List<Cat>();
        var cat = GetNextCat();

        while(cat != null)
        {
            catList.Add(cat);
            cat = GetNextCat();
        }

        return catList;
    }
}

两个版本的属性产生相同的结果。那么,为什么 NHibernate 与第一个示例不同,而与第二个示例一起使用呢?是不是 NHibernate 没有设置为处理来自yield return 的编译器生成的类?还是这只是 Fluent 的问题?

【问题讨论】:

    标签: c# nhibernate fluent-nhibernate


    【解决方案1】:

    属性的结果是不同的。

    第一个生成一个生成的 IEnumerable(迭代器),第二个返回一个生成的列表。 NHibernate 尝试将 ICollection/ISet/Ilist(取决于 AsBag/Set/List)包装在一个对 IEnumerable 失败而对 List 成功的 persistentBag/Set/List 中。

    但是,两者都不正确,因为 NHibernate 无法动态更改生成的对象的轨道,因此第二个代码将运行但会产生疯狂的结果和/或异常。

    结论:根本不映射此属性,因为它是在代码中生成的,而不是从数据库中加载的。加载/映射GetNextCat() 用于获取下一只猫的持久数据。

    【讨论】:

    • 有趣。在这种情况下,您是否建议避免将任何属性映射为只读,或者仅当属性是某种集合(或复杂对象)时?
    • readonly 有它的用途,但你有一个完全不同的问题。您有一个像 public double Cost { get { return Price * Cost; } } 这样生成的属性,并且没有只读属性 public double Cost { get { return _cost; } }
    猜你喜欢
    • 1970-01-01
    • 2023-03-07
    • 2018-03-22
    • 1970-01-01
    • 2010-10-11
    • 2017-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多