Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何控制急切加载数据映射器的获取深度?_C#_.net_Database_Design Patterns_C# 2.0 - Fatal编程技术网

C# 如何控制急切加载数据映射器的获取深度?

C# 如何控制急切加载数据映射器的获取深度?,c#,.net,database,design-patterns,c#-2.0,C#,.net,Database,Design Patterns,C# 2.0,我有一个datamapper类,它可以加载任何没有惰性属性的属性。我有两个实体,国家和国家,国家与国家的关系是相反的,因为它包含了该国所有国家的列表,国家与国家的关系是向前的,因为它有一个财产国,它被分配到该国。但是,如果我尝试检索其中一个对象,让我们假设一个状态,这就是发生的情况: 状态由映射器加载 Mapper到达了一个渴望拥有房产的国家 映射器检索该州的国家/地区 地图绘制者载入全国 映射器达到状态的渴望集合属性 映射器加载一个状态列表,并在可能的地方使用缓存开始映射每个单独的状态 国家/

我有一个datamapper类,它可以加载任何没有惰性属性的属性。我有两个实体,国家和国家,国家与国家的关系是相反的,因为它包含了该国所有国家的列表,国家与国家的关系是向前的,因为它有一个财产国,它被分配到该国。但是,如果我尝试检索其中一个对象,让我们假设一个状态,这就是发生的情况:

  • 状态由映射器加载
  • Mapper到达了一个渴望拥有房产的国家
  • 映射器检索该州的国家/地区
  • 地图绘制者载入全国
  • 映射器达到状态的渴望集合属性
  • 映射器加载一个状态列表,并在可能的地方使用缓存开始映射每个单独的状态
  • 国家/地区中加载的每个州的转到1
  • 我不知道如何才能避免这种循环。所以我主要是在寻找想法。我会发布任何人问我的代码,但这个过程包含了很多行代码,所以我不想用大量的代码来回答这个问题

    提前谢谢

    编辑:

    在遵循Matt Howells的建议并深入研究数据映射器模式之后,Martin Fowler确实在第169页和第170页提到了循环引用。他的建议是使用空对象并将其加载到标识映射中,然后返回它,从而停止递归加载。我现在已经读了1000遍了,我仍然不明白这是如何停止加载的,而且我还不知道何时或者如何知道何时将这个空对象加载到我的身份映射中。很抱歉,我在这里说的太多了,但这似乎就在我头上飞过


    再次感谢。

    数据映射器应该捕获循环引用。它是一个自制的数据映射器吗?

    考虑通过存储库加载对象,该存储库跟踪已加载的对象

    编辑:如果你正在做你自己的ORM(即使你不是),我强烈推荐Martin Fowler的《企业应用程序架构模式》一书。我模模糊糊地记得他在书中谈到这个循环的情况,所以这可能会对你有所帮助

    编辑2:
    在循环的第4步和第5步,如果您已经加载了国家/地区,则无需急于加载其状态,因为它们应该已经加载。这打破了无限循环。

    我只是想发布我提出的解决方案,但是我相信有很多方法可以剥这只猫的皮

    这是我创建的FetchDepthSuss:

    public static class FetchDepthCounter
    {
        private static Dictionary<Type, int> _DepthCounter;
        private static int _MaxDepth = 3;
    
        static FetchDepthCounter()
        {   
            _DepthCounter = new Dictionary<Type, int>();
        }
    
        public static void SetDepth(int depth)
        {
            _MaxDepth = depth;
        }
    
        public static void ResetCounter()
        {
            _DepthCounter.Clear();
        }
    
        public static bool IncrementCounter(Type entityType)
        {
            if(!_DepthCounter.ContainsKey(entityType))
            {
                _DepthCounter.Add(entityType, 0);
                return true;
            }
    
            if(_DepthCounter[entityType] < _MaxDepth)
            {
                ++_DepthCounter[entityType];
                return true;
            }
    
            return false;
        }
    
    }
    

    就是这样,似乎就是这样。我所有的单元测试都通过了。谢谢大家的帮助。我希望这对以后的人有所帮助。再说一次,将它包装成一个工作单元模式可能会容易得多,最终我可能会这样做,但现在这项工作已经完成。

    它是自主开发的……我将如何为此实施某种形式的捕获?这就是我在调整datamapper代码以包含此监视时所遇到的问题。请记录您已经访问的属性,并将当前属性与该列表进行比较。因此,获取深度通常在属性级别实现,而不是在对象级别实现?假设我的最大获取深度为3,那么属性可以映射3次,但对象图的深度可能会明显高于此值。我的假设正确吗?我确实记录了所有加载的对象。然而,我想我只是太过密集,我无法找到一种方法来利用这个。我试图控制获取深度,但它必须针对发起人进行控制。我试图实现的基本目标是:状态(发起人)->国家->状态->[停止],但当我映射处于状态的每个单独状态时,实体不知道请求发起人的存在。因此,似乎不可能对发起者应用特定的计数器。是吗?我工作时把它放在桌子上,明天我会看看能不能找到什么。谢谢。我补充了马丁·福勒的建议,但我还是迷路了。有什么建议吗?
    if(isDto)
    {
        if (!FetchDepthCounter.IncrementCounter(property.ComponentType))
            return;
    }