调试和属性加载

时间:2016-03-07 11:48:34

标签: c# debugging properties breakpoints

我有一个对象代表我的数据库中的表记录,例如' Project'。

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

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

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

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

在代码中,有没有办法在调试窗口中不通过这部分代码? 例如,类似的东西:

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,但没有任何可以做类似的事情。

1 个答案:

答案 0 :(得分: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,除非您打开&#34;原始视图&#34;在第一个断点处。

enter image description here