在UWP中使用Sqlite.Net时的性能问题

时间:2016-10-25 04:42:55

标签: sqlite windows-runtime uwp

我正在使用带有SQLite.Net的SQLite,但每次插入都需要大约15-20秒。虽然我有一个复杂的表格,如下所示。

namespace Models
{
    //SQLite Table AssessmentQuestions
    [Table("AssessmentQuestions")]
    public class AssessmentQuestion : INotifyPropertyChanged
    {
        //Autogenerate
        private int _id;
        [PrimaryKey, AutoIncrement]
        [JsonIgnore]
        public int Id
        {
            get
            {
                return _id;
            }
            set
            {
                this._id = value;
                OnPropertyChanged(nameof(Id));
            }
        }
        private int _month;
        public int Month
        {
            get
            {
                return _month;
            }
            set
            {
                this._month = value;
                OnPropertyChanged(nameof(_month));
            }
        }

        //Some other ids as varibles here too

        [OneToMany(CascadeOperations = CascadeOperation.All)]
        public List<Facility> QuestionFacilityModel { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            this.PropertyChanged?.Invoke(this,
                new PropertyChangedEventArgs(propertyName));
        }
    }

    //SQLite Table Facility
    [Table("Facilities")]
    public class Facility : INotifyPropertyChanged
    {
        //Autogenerate
        private int _id;
        [PrimaryKey, AutoIncrement]
        [JsonIgnore]
        public int Id
        {
            get
            {
                return _id;
            }
            set
            {
                this._id = value;
                OnPropertyChanged(nameof(Id));
            }
        }

        private int _assessmentScheduleId;
        public int AssessmentScheduleId
        {
            get
            {
                return _assessmentScheduleId;
            }
            set
            {
                this._assessmentScheduleId = value;
                OnPropertyChanged(nameof(_assessmentScheduleId));
            }
        }

        //Some other ids as varibles here too

        [ForeignKey(typeof(AssessmentQuestion))]
        [JsonIgnore]
        public int AssessmentQuestionId { get; set; }

        [ManyToOne(CascadeOperations = CascadeOperation.All)]
        [JsonIgnore]
        public AssessmentQuestion AssessmentQuestion { get; set; }

        [OneToMany(CascadeOperations = CascadeOperation.All)]
        public ObservableCollection<SubFacility> SubFacility { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            this.PropertyChanged?.Invoke(this,
                new PropertyChangedEventArgs(propertyName));
        }
    }

    //SQLite Table Sub Facility
    [Table("SubFacilities")]
    public class SubFacility : INotifyPropertyChanged
    {
        //Autogenerate
        private int _id;
        [PrimaryKey, AutoIncrement]
        [JsonIgnore]
        public int Id
        {
            get
            {
                return _id;
            }
            set
            {
                this._id = value;
                OnPropertyChanged(nameof(Id));
            }
        }

        //Some other ids as varibles here too

        [ForeignKey(typeof(Facility))]
        [JsonIgnore]
        public int FacilityId { get; set; }

        [ManyToOne(CascadeOperations = CascadeOperation.All)]
        [JsonIgnore]
        public Facility Facility { get; set; }

        [OneToMany(CascadeOperations = CascadeOperation.All)]
        public List<Questions> Questions { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            this.PropertyChanged?.Invoke(this,
                new PropertyChangedEventArgs(propertyName));
        }
    }

    //SQLite Table Questions
    [Table("Questions")]
    public class Questions : INotifyPropertyChanged
    {
        public Questions()
        {
            AssessmentImages = new string[0];
        }

        //Autogenerate
        private int _id;
        [PrimaryKey, AutoIncrement]
        [JsonIgnore]
        public int Id
        {
            get
            {
                return _id;
            }
            set
            {
                this._id = value;
                OnPropertyChanged(nameof(_id));
            }
        }
        private int _assessmentScheduleId;
        public int AssessmentScheduleId
        {
            get
            {
                return _assessmentScheduleId;
            }
            set
            {
                this._assessmentScheduleId = value;
                OnPropertyChanged(nameof(_assessmentScheduleId));
            }
        }
              //Some other ids as varibles here too

        [SQLite.Net.Attributes.Ignore]
        public virtual string[] AssessmentImages { get; set; }

        private bool _imageExists;
        public bool ImageExists
        {
            get
            {
                return _imageExists;
            }
            set
            {
                this._imageExists = value;
                OnPropertyChanged(nameof(_imageExists));
            }
        }

        [ForeignKey(typeof(SubFacility))]
        [JsonIgnore]
        public int SubFacilityId { get; set; }

        [ManyToOne(CascadeOperations = CascadeOperation.All)]
        [JsonIgnore]
        public SubFacility SubFacility { get; set; }

        [OneToMany(CascadeOperations = CascadeOperation.All)]
        public List<ControlTypes> ControlTypes { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            this.PropertyChanged?.Invoke(this,
                new PropertyChangedEventArgs(propertyName));
        }
    }

    //SQLite Table ControlTypes
    [Table("ControlTypess")]
    public class ControlTypes
    {
        //Autogenerate
        private int _id;
        [PrimaryKey AutoIncrement]
        [JsonIgnore]
        public int Id
        {
            get
            {
                return _id;
            }
            set
            {
                this._id = value;
                OnPropertyChanged(nameof(_id));
            }
        }
        private string _answerValue;
        public string AnswerValue
        {
            get
            {
                return _answerValue;
            }
            set
            {
                this._answerValue = value;
                OnPropertyChanged(nameof(_answerValue));
            }
        }
        private int _questionValueId;
        public int QuestionValueId
        {
            get
            {
                return _questionValueId;
            }
            set
            {
                this._questionValueId = value;
                OnPropertyChanged(nameof(_questionValueId));
            }
        }
        private string _questionValueName;
        public string QuestionValueName
        {
            get
            {
                return _questionValueName;
            }
            set
            {
                this._questionValueName = value;
                OnPropertyChanged(nameof(_questionValueName));
            }
        }
        private string _questionTypeId;
        public string QuestionTypeId
        {
            get
            {
                return _questionTypeId;
            }
            set
            {
                this._questionTypeId = value;
                OnPropertyChanged(nameof(_questionTypeId));
            }
        }
        private int _score;
        public int Score
        {
            get
            {
                return _score;
            }
            set
            {
                this._score = value;
                OnPropertyChanged(nameof(_score));
            }
        }
        private string _assessmentDetailId;
        public string AssessmentDetailId
        {
            get
            {
                return _assessmentDetailId;
            }
            set
            {
                this._assessmentDetailId = value;
                OnPropertyChanged(nameof(_assessmentDetailId));
            }
        }
        private string _assessmentAnswerId;
        public string AssessmentAnswerId
        {
            get
            {
                return _assessmentAnswerId;
            }
            set
            {
                this._assessmentAnswerId = value;
                OnPropertyChanged(nameof(_assessmentAnswerId));
            }
        }

        [ForeignKey(typeof(Questions))]
        [JsonIgnore]
        public int QuestionsId { get; set; }

        [ManyToOne(CascadeOperations = CascadeOperation.All)]
        [JsonIgnore]
        public Questions Questions { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            this.PropertyChanged?.Invoke(this,
                new PropertyChangedEventArgs(propertyName));
        }
    }

    public class StringOrArrayConverter : JsonConverter
    {
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            switch (reader.TokenType)
            {
                case JsonToken.String:
                case JsonToken.Null:
                    return reader.Value;
                case JsonToken.StartArray:
                    reader.Read();
                    if (reader.TokenType != JsonToken.EndArray)
                        throw new JsonReaderException("Empty array expected.");
                    return "";
            }
            throw new JsonReaderException("Expected string or null or empty array.");
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            //var item = (string[])value;
            //writer.WriteValue(item);
            serializer.Serialize(writer, value);
        }

        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(string);
        }
    }
}

我的sql连接

var platform = new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT();
var connectionWithLock = new SQLiteConnectionWithLock(platform, _connectionParameters);
var connection = new SQLiteAsyncConnection(() => connectionWithLock);
SQLite.Net.Async.SQLiteAsyncConnection database = connection;

插入看起来像

database.InsertWithChildrenAsync(assessmentQuestion,true).ConfigureAwait(false);

我是sqlite的新手,所以我想知道性能如何如此糟糕。我还使用了SQLiteNetExtensionsAsync.Extensions。我尝试在没有异步调用的情况下使用并具有相同的性能。由于我在循环中进行了大量的30-40次插入,因此需要花费很多时间。我怎样才能改善这一点。

另请注意,一个插入可以有多个嵌套插入,因为对象很复杂,但平均一次插入相当于35-45个不同子对象的单独插入。这种嵌套似乎导致了这个问题。

1 个答案:

答案 0 :(得分:1)

在事务中调用此方法应该使其更快。这是SQLite本身的推荐:http://www.sqlite.org/faq.html#q19

此致