0

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

当我重新启动应用程序并加载父行和 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

变种试用=新试用{“tset1”};

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



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

1 回答 1

3

就这样。

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

请参阅NHibernate 会话管理如何在 WPF 应用程序中确定 NHibernate 会话和事务的范围

来自文章

NHibernate 桌面应用程序的一个常见不良做法是为整个应用程序设置一个全局会话。这是一个问题,原因有很多,...

于 2012-07-12T10:38:47.287 回答