C# 使用迭代器的只读属性的NHibernate映射(收益率返回)

C# 使用迭代器的只读属性的NHibernate映射(收益率返回),c#,nhibernate,fluent-nhibernate,C#,Nhibernate,Fluent Nhibernate,是否可以映射NHibernate中使用迭代器(即,yield-return)的只读属性 例如,假设我们有一个Person类,该类具有只读IEnumerable Cats属性和一个名为GetNextCat()的方法,该方法获取序列中的下一个cat 以下是可能的映射: public class PersonMap : ClassMap<Person> { public PersonMap() { HasMany(x => x.Cats).Access

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

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

以下是可能的映射:

public class PersonMap : ClassMap<Person>
{
    public PersonMap()
    {
        HasMany(x => x.Cats).Access.ReadOnly(); // also tried .AsSet() and .AsBag()
    }
}
公共类PersonMap:ClassMap
{
公众人物地图()
{
HasMany(x=>x.Cats).Access.ReadOnly();//还尝试了.AsSet()和.AsBag()
}
}
下面是
IEnumerable 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;
    }
}
//失败:
//System.InvalidCastException:无法将类型为“d\u 0”的对象强制转换为
//键入'System.Collections.Generic.ICollection'1[MyProject.Cat]'。
公共虚拟数字猫
{
得到
{
var cat=GetNextCat();
while(cat!=null)
{
回归猫;
cat=GetNextCat();
}
屈服断裂;
}
}
//工作
公共虚拟数字猫
{
得到
{
var catList=新列表();
var cat=GetNextCat();
while(cat!=null)
{
catList.Add(cat);
cat=GetNextCat();
}
返回catList;
}
}

属性的两个版本产生相同的结果。那么,为什么NHibernate与第一个示例不同,却与第二个示例一起工作?是不是NHibernate没有被设置为处理编译器从
生成的类并返回
?或者这只是Fluent的一个问题?

属性的结果是不同的

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

然而,这两种方法都是不正确的,因为NHibernate不能改变动态生成的对象,所以第二个代码将运行,但会产生疯狂的结果和/或异常


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

有趣。在这种情况下,您会建议避免将任何属性映射为只读,还是仅当该属性是某种集合(或复杂对象)时才进行映射?只读有其用途,但您会遇到完全不同的问题。您有一个生成的属性,如
public double Cost{get{return Price*Cost;}}
,并且没有只读属性
public double Cost{get{return\u Cost;}}