SQLite,检查数据库是否存在并具有正确的数据,更有效的方法

问题描述 投票:0回答:1

我正在制作Xamarin.Android应用程序,并且我使用SQLite来处理某些图像(超过300个)。我将图像作为模板存储在一组5张图像中,如下所示:

    [Table("Templates")]
    public class Template
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
        public string Name { get; set; }
        public int Category { get; set; }
        [OneToMany]
        public List<TemplateImage> TemplateImages { get; set; }
        public string ImagesHash { get; set; }
    }
    [Table("TemplateImages")]
    public class TemplateImage
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }
        public int Category { get; set; }
        public int Image { get; set; }
        [ForeignKey(typeof(Template))]
        public int TemplateId { get; set; }
    }

并且是第一次启动该应用程序时,我使用此代码来检查数据库是否存在或创建数据库:

public static void AddTemplate(int category, List<int> images)
        {
            var tmpl = new Template()
            {
                Category = category,
            };
            if (images != null)
            {
                var img1 = new TemplateImage()
                {
                    Category = category,
                    Image = images[0],
                };
                var img2 = new TemplateImage()
                {
                    Category = category,
                    Image = images[1],
                };
                var img3 = new TemplateImage()
                {
                    Category = category,
                    Image = images[2],
                };
                var img4 = new TemplateImage()
                {
                    Category = category,
                    Image = images[3],
                };
                var img5 = new TemplateImage()
                {
                    Category = category,
                    Image = images[4],
                };
                tmpl.TemplateImages = new List<TemplateImage>() { img1, img2, img3, img4, img5 };
            }
            tmpl.ImagesHash = Guid.NewGuid().ToString();

            DatabaseHelper.Db().InsertAll(tmpl.TemplateImages);
            DatabaseHelper.Db().Insert(tmpl);
            DatabaseHelper.Db().UpdateWithChildren(tmpl);
        }

        public static List<Template> GetAllTemplates()
        {
            return DatabaseHelper.Db().GetAllWithChildren<Template>();
        }

        public static Template GetTemplate(int id)
        {
            var result = DatabaseHelper.Db().GetWithChildren<Template>(id);
            if (result == null)
            {
                result = DatabaseHelper.Db().GetAllWithChildren<Template>().Where(record => record.Category == (int)TemplateCategory.Emojis).OrderBy(record => record.Id).FirstOrDefault();
            }
            return result;
        }

public static void CreateDB()
        {
            DatabaseHelper.Db().RunInTransaction(() =>
            {
                DatabaseHelper.Db().CreateTable<Template>();
                DatabaseHelper.Db().CreateTable<TemplateImage>();
                if (DatabaseHelper.Db().Table<Template>().Count() != 0)
                {
                    return;
                }
                AddTemplate(

                    (int)TemplateCategory.Emojis,
                    new List<int>
                    {
                Resource.Drawable.ic_angry,
                Resource.Drawable.ic_sad,
                Resource.Drawable.ic_neutral,
                Resource.Drawable.ic_happy,
                Resource.Drawable.ic_smiling,
                    }
                );
                AddTemplate(

    (int)TemplateCategory.Emojis,
     new List<int>
                {
                Resource.Drawable.ic_emoji_01_1,
                Resource.Drawable.ic_emoji_01_2,
                Resource.Drawable.ic_emoji_01_3,
                Resource.Drawable.ic_emoji_01_4,
                Resource.Drawable.ic_emoji_01_5,
    }
    );

...//AND many more AddTemplate() functions like those 2.
}

这很好用,直到有一天我在非常罕见的情况下看到了[[有时应用程序正在显示..其他图像,我从那些图像中随机选择了它。因此,我意识到出于某些原因,compiler决定要更改ImageDrawables的ResourceId,因此,尽管事实上我的数据库存在,但这是完全错误的,

因此,我已经开始重新考虑做这种事情的正确方法是什么,而不必每次都重新创建数据库时,我发现了每次坏数据库时都重新创建数据库的想法,但是如果这是唯一正确的方法,并且只有这样我才能100%确定结果,我会坚持下去。

我从测试中看到,通常第一组图像已更改(第一个模板),我在考虑做这样的事情是否是一个好主意:

public static bool ExistingDBItemsFound(int id) { var returnValue = false; var result = GetTemplate(1); if (result.TemplateImages.Count == 5) { if (result.TemplateImages[0].Image == Resource.Drawable.ic_angry && result.TemplateImages[1].Image == Resource.Drawable.ic_sad && result.TemplateImages[1].Image == Resource.Drawable.ic_neutral && result.TemplateImages[1].Image == Resource.Drawable.ic_happy && result.TemplateImages[1].Image == Resource.Drawable.ic_smiling) returnValue = true; } return returnValue; }

但是如果我做这样的事情,我如何才能确保所有其他资源ID都是正确的?我只检查300个以上的5个。 

我是否可以避免在每次创建应用程序的数据库项时重新创建?我是怎么办?

有没有一种方法可以将资源以其他格式而不是resourceId的形式保存在数据库中?

c# android sqlite xamarin xamarin.android
1个回答
1
投票
资源ID绝不应该用作唯一标识符,因为编译器可以在某些时候轻松更改它们,所以最好的方法是完全避免使用它们。

解决我的问题的一种方法可能是使用此处的建议答案:Best way to store Resource id in Database on Android

获取图标名称

var iconName = Context.Resources.GetResourceEntryName( Resource.Drawable.your_icon );

然后从名称获取ID:

var id = Context.Resources.GetIdentifier( iconName, "drawable", Context.PackageName )

这样,即使资源ID发生变化,只要不重命名资源,我们都将获得正确的图像。

[如果您还想检查用户数据库是否具有与apk数据库相同的值,则可以执行@martin venter建议的操作并以某种方式创建哈希(例如:资源名称的哈希)并进行比较]]

© www.soinside.com 2019 - 2024. All rights reserved.