NHibernate简单事务至少需要10秒

时间:2012-07-12 10:04:58

标签: .net wpf hibernate nhibernate sql-server-ce

我在wpf应用程序上使用NHibernate和SqlCe数据库。 我创建一个父行,并在父行上添加大约10K个子记录。 比任何简单的事务,如在任何表上插入一行至少需要10个seconrds。

当我重新启动应用程序并加载父行和10K子行时,任何任何事务都正常运行。

可能是什么原因?

试用课

public class Trial : JobsBase, INotifyPropertyChanged, ISoftDelete, IUniqueName, IDataErrorInfo, IFilter
{
    private int newrows;
    private int rows;
    private string name;
    private int cols;
    private int newcols;
    private string description;


    public Trial()
    {
        TrialId = new Guid();

    }

    public virtual Guid TrialId { get;  set; }

    public virtual string Name
    {
        get
        {
            return name;
        }
        set
        {

            if (name == value) return;
            name = value;
            FirePropertyChangedEvent("Name");
        }
    }
    public virtual int Rows
    {
        get
        {
            return rows;
        }
        set
        {

            newrows = value;
            if (newrows * cols > 10000) { return; }
            if (rows == value) return;
            BuildCells(rows, cols, value, cols);
            rows = value;
            FirePropertyChangedEvent("Rows");
        }
    }
    public virtual int Cols
    {
        get
        {

            return cols;
        }
        set
        {
            newcols = value;
            if (newcols * rows > 10000) { return; }
            if (value == cols) return;
            BuildCells(rows, cols, rows, value);
            cols = value;
            FirePropertyChangedEvent("Cols");
        }
    }








    public virtual string Description
    {
        get
        {
            return description;
        }
        set
        {
            if (description == value) return;
            description = value;
            FirePropertyChangedEvent("Description");
        }
    }







    public virtual void CleanUpRows(int oldrows, int newrows)
    {
        for (int r = newrows; r < oldrows; r++)
        {
            for (int c = 0; c < cols; c++)
            {
                //cell to delete
                var delCell = new Cell() { X = c, Y = r };
                int index;
                if ((index = cells.IndexOf(delCell)) > -1)
                {
                    cells.RemoveAt(index);
                }
            }
        }
    }
    public virtual void CleanUpColumns(int oldcols, int newcols)
    {
        for (int c = newcols; c < oldcols; c++)
        {
            for (int r = 0; r < rows; r++)
            {
                //cell to delete
                var delCell = new Cell() { X = c, Y = r };
                int index;
                if ((index = cells.IndexOf(delCell)) > -1)
                {
                    cells.RemoveAt(index);
                }
            }
        }
    }
    public virtual void BuildCells(int oldrows, int oldcols, int newrows, int newcols)
    {

        //remove cells if rows cols size decreases
        if (oldrows > newrows) CleanUpRows(oldrows, newrows);
        if (oldcols > newcols) CleanUpColumns(oldcols, newcols);
        Debug.WriteLine("build cells: " +DateTime.Now.ToLongTimeString() );
        for (int i = 0; i < newcols; i++)
        {

            for (int j = 0; j < newrows; j++)
            {
                AddCell(new Cell { X = i, Y = j, Active = true });
            }
        }
        Debug.WriteLine("end build cells: " + DateTime.Now.ToLongTimeString());

    }
    private IList<Cell> cells = new List<Cell>();


    public virtual IList<Cell> Cells
    {
        get { return cells; }
        set { cells = value; }
    }

    public virtual void AddCell(Cell cell)
    {

        if (!HasCell(cell))
        {
            cell.Trial = this;
            cells.Add(cell);
        }
    }
    public virtual void RemoveCell(Cell cell)
    {
        cells.Remove(cell);
    }
    public virtual bool HasCell(Cell cell)
    {
        return cells.Contains(cell);
    }
    public virtual bool HasCell(int x, int y)
    {
        return HasCell(new Cell() { X = x, Y = y });
    }
    public virtual Cell SetCellActive(int x, int y, bool active)
    {
        int i = Cells.IndexOf(new Cell() { X = x, Y = y });
        Cells[i].Active = active;
        FireCellChanged(new CellEventArgs() { X = x, Y = y });
        return Cells[i];

    }
    public virtual Cell GetCell(int x, int y)
    {
        int i = Cells.IndexOf(new Cell() { X = x, Y = y });
        return i >= 0 ? Cells[i] : null;
    }


    public virtual event PropertyChangedEventHandler PropertyChanged;
    public virtual event EventHandler<CellEventArgs> CellChanged;

    private void FireCellChanged(CellEventArgs e)
    {
        EventHandler<CellEventArgs> changed = CellChanged;
        if (changed != null) changed(this, e);
    }

    private void FirePropertyChangedEvent(string propertName)
    {
        if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertName));
    }

    public override string ToString()
    {
        return TrialId.ToString();
    }

    public override bool Equals(object obj)
    {
        if (this == obj) return true;

        var other = obj as Trial;
        if (other == null) return false;

        return TrialId.Equals(other.TrialId);

    }




    public override int GetHashCode()
    {
        return TrialId.GetHashCode();
    }

    public virtual string this[string columnName]
    {
        get
        {
            string result = null;
            if (columnName == "Cols" || columnName == "Rows")
            {
                if (this.newcols * this.newrows > 10000)
                {
                    result = "No of cells must not exceed 10000";
                }
            }

            return result;
        }
    }

    public virtual string Error
    {
        get { return null; }
    }


    }

}
public class CellEventArgs : EventArgs
{
    public int X { get; set; }
    public int Y { get; set; }
}

细胞

 public class Cell : INotifyPropertyChanged
    {
        public Cell()
        {
            CellId = Guid.NewGuid();
        }
        public virtual Guid CellId { get; set; }
        public virtual int MagazinNumber { get; set; } 
        public virtual int X { get; set; }
        public virtual int Y { get; set; }
        public virtual Trial Trial { get; set; }
        public virtual bool Active { get; set; }

        public virtual string CustomId { get; set; }

        public override string ToString()
        {
            return CellId.ToString();
        }

        public virtual bool EqualsById { get; set; }
        public override bool Equals(object obj)
        {
            if (this == obj) return true;

            var other = obj as Cell;
            if (other == null) return false;
            return other.EqualsById ? CellId.Equals(other.CellId) : X.Equals(other.X) && Y.Equals(other.Y);
        }

        public override int GetHashCode()
        {
            return CellId.GetHashCode();
        }

        private IDictionary<string, float> _datalist;
        public virtual IDictionary<string, float> Datalist
        {
            get
            {
                if(_datalist==null)
                {
                    _datalist= new Dictionary<string, float>();
                    if (data != null)
                    {
                        var document = new XmlDocument();
                        document.LoadXml(data);
                        foreach (XmlNode childNode in document.FirstChild.ChildNodes)
                        {
                            if (childNode.Attributes == null) continue;

                            string key = childNode.Attributes["key"].Value;
                            float val = float.Parse(childNode.Attributes["value"].Value);
                            SetExtraField(key, val);
                        }
                    }

                }
                return _datalist;
            }

        }

        private void SetExtraField(string key, float value)
        {
            if (Datalist.ContainsKey(key))
            {
                Datalist[key] = value;
            }
            else
            {
                Datalist.Add(key, value);
            }
        }

        private float? GetExtraField(string key)
        {
            float value;
            return Datalist.TryGetValue(key, out value) ? (float?)value : null;
        }

        private int? GetExtraFieldInt(string key)
        {
            float value;
            return Datalist.TryGetValue(key, out value) ? (int?)value : null;
        }
        private string data;
        public virtual string Data
        {
            get
            {
                string xml = @"<datas>";
                foreach (var f in Datalist)
                {
                    xml += string.Format("<data key='{0}' value='{1}' />", f.Key, f.Value);
                }
                xml += "</datas>";
                return xml;
            }
            set
            {
                data = value;
            }
        }

将试验添加到db

var trial = new Trial {“tset1”};

        trial.Rows = 10;
        trial.Cols = 1000;



        trial.Deleted = false;
        trial.BuildCells(10, 1000, 10, 1000);
        TrialDAO.Instance().Add(trial);     

1 个答案:

答案 0 :(得分:3)

就是这样。

通过应用程序生命周期的单个会话是您的原因。请参阅有关如何管理会话的nhibernate文档。

请参阅NHibernate session managementHow to scope NHibernate sessions and transactions in a WPF application

来自article

  

NHibernate桌面应用程序的一个常见错误做法是为整个应用程序提供单个全局会话。出于多种原因这是一个问题,......