2016-03-07 58 views
2

我有一个对象,表示我的数据库中的表的记录,例如'Project'。调试和属性加载

我的用户类具有不同的属性,这些属性是其他表的记录,例如'客户'或'会计'。那些也有相关表格的属性。

这些属性中的每一个都返回一个本地值(已经加载),如果不为空,并且没有加载的信息,它会生成一个从数据库中获取该值的请求。

我的问题如下:当我设置断点并在调试窗口中检查对象时,它会自动加载属性的所有值,因此请求数据库。

在这种情况下,我目前无法获得对象的精确和静态快照。

有没有一种方法,在代码中,如果在调试窗口中不经过这部分代码? 举例来说,这样的事情:

public MyBaseObject GetProperty<T>(string columnName_, string alias_ = null) where T : MyBaseObject, new() 
{ 
    var ret = GetExtract<T>(columnName_, alias_); 

    // if the data are loaded 
    if (ret.Id != null) 
     return ret; 

    // Fake boolean I would like 
    if(InDebugWindowAfterAbreakPointForInstance) 
     return ret; 
    else 
     ret = LoadFromDatabase<T>(columnName_, alias_) 
    return ret; 
} 

我发现不同的属性与调试器,像DebuggerStepperBoundaryAttribute,但没有什么可以做类似的东西。

+0

为什么用C#和D标记这个标记?请删除您未使用的语言标签。 –

回答

0

在这样的情况下,我知道的唯一方法是对每个类型使用DebuggerTypeProxy,然后在该代理中直接访问支持字段,而不是通过导致数据库查找发生的属性。

这是一个简单的示例程序。

public class Program 
{ 
    public static void Main(string[] args) 
    { 
     var client = new Client(); 
     Debugger.Break(); 
     Debugger.Break(); 
    } 
} 

[DebuggerTypeProxy(typeof(ClientDebugView))] 
public class Client : MyBaseObject 
{ 
    private string _firstName; 
    private string _lastName; 

    public string FirstName 
    { 
     get 
     { 
      if (_firstName == null) 
       _firstName = GetProperty<string>("FirstName"); 

      return _firstName; 
     } 
     set 
     { 
      if (Equals(_firstName, value)) 
       return; 
      _firstName = value; 
      UpdateDatabase(_firstName, "FirstName"); 
     } 
    } 

    public string LastName 
    { 
     get 
     { 
      if (_lastName == null) 
       _lastName = GetProperty<string>("LastName"); 

      return _lastName; 
     } 
     set 
     { 
      if (Equals(_lastName, value)) 
       return; 
      _lastName = value; 
      UpdateDatabase(_lastName, "LastName"); 
     } 
    } 

    internal class ClientDebugView : MyBaseObjectDebugView 
    { 
     private readonly Client _client; 

     public ClientDebugView(Client client) 
      : base(client) 
     { 
      _client = client; 
     } 

     public string FirstName 
     { 
      get { return _client._firstName; } 
     } 

     public string LastName 
     { 
      get { return _client._lastName; } 
     } 
    } 
} 

[DebuggerTypeProxy(typeof(MyBaseObjectDebugView))] 
public class MyBaseObject 
{ 
    private Guid? _id; 

    public Guid? Id 
    { 
     get 
     { 
      if (_id == null) 
       _id = GetProperty<Guid?>("Id"); 

      return _id; 
     } 
     set 
     { 
      if (Equals(_id, value)) 
       return; 
      _id = value; 
      UpdateDatabase(_id, "Id"); 
     } 
    } 

    //Fake loading data from a database. 
    protected T GetProperty<T>(string columnName) 
    { 
     object ret = null; 
     switch (columnName) 
     { 
      case "Id": 
       ret = Guid.NewGuid(); 
       break; 
      case "LastName": 
       ret = "Smith"; 
       break; 
      case "FirstName": 
       ret = "John"; 
       break; 
      default: 
       ret = null; 
       break; 
     } 

     return (T)ret; 
    } 

    protected void UpdateDatabase<T>(T id, string s) 
    { 
     throw new NotImplementedException(); 
    } 

    internal class MyBaseObjectDebugView 
    { 
     private readonly MyBaseObject _baseObject; 

     public MyBaseObjectDebugView(MyBaseObject baseObject) 
     { 
      _baseObject = baseObject; 
     } 

     public Guid? Id 
     { 
      get { return _baseObject._id; } 
     } 
    } 
} 

如果您查看在调试器中client对象,你会看到它留下的后盾领域null的两个断点之间,除非你打开“原始视图”在第一个断点。

enter image description here