[在将数据插入数据库之前检查sqlite-net中是否存在数据

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

我正在制作一个将使用“模板”的Xamarin.Android应用程序,模板是这样的:

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

我希望所有TemplateImages对象在我的数据库中都是唯一的,属性Unique不执行任何操作,原因是我猜因为TemplateImage表具有自动增量ID,所以无论Image或ImageHash是2条记录中相同。

我当时在想,我还能如何确定TemplateImages是唯一的(Notice:当我说唯一时,我的意思是,没有其他的[[List对于每个TemplateImage,按相同顺序<< Image>)。而且我还使用图像的ResourceID作为图像,这是错误的,因为它们可能会在每次新编译的应用程序更新时发生变化。

因此,我决定从图像中创建一个哈希md5。我发现在

Xamarin.Android

中加载资源图像(我的图像是

vector .xml

文件)的唯一方法是将资源转换为位图,然后将位图转换为字节,然后md5的字节。而且我也应该为模板项添加一个哈希字符串。因此,我通过将图像的所有byte []合并为一个,然后使用它来为模板创建md5哈希。我为此工作创建了这个疯狂的代码:

public static string GetMD5Hash(byte[] content) { using (var md5 = MD5.Create()) { byte[] computedHash = md5.ComputeHash(Encoding.UTF8.GetBytes(BitConverter.ToString(content).Replace("-", ""))); return new System.Runtime.Remoting.Metadata.W3cXsd2001.SoapHexBinary(computedHash).ToString(); } } private static SQLiteConnection instance; public static SQLiteConnection db() { if (instance == null) instance = new SQLiteConnection(System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "TemplatesData.db")); return instance; } public static void CloseConnection() { if (instance != null) { instance.Close(); instance.Dispose(); instance = null; } } } public class TemplateDB { public static byte[] ConcatByteList(List<byte[]> list) { return list .SelectMany(a => a) .ToArray(); } public static Bitmap GetBitmapFromVectorDrawable(Context context, int drawableId) { Drawable drawable = ContextCompat.GetDrawable(context, drawableId); if (Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.Lollipop) { drawable = (DrawableCompat.Wrap(drawable)).Mutate(); } Bitmap bitmap = Bitmap.CreateBitmap(drawable.IntrinsicWidth, drawable.IntrinsicWidth, Bitmap.Config.Argb8888); Canvas canvas = new Canvas(bitmap); drawable.SetBounds(0, 0, canvas.Width, canvas.Height); drawable.Draw(canvas); return bitmap; } public byte[] DrawableToByteArray(int resourceId) { var context = AppState.ApplicationState; using (var bitmap = GetBitmapFromVectorDrawable(context, resourceId)) { int size = bitmap.ByteCount; byte[] byteArray = new byte[size]; ByteBuffer byteBuffer = ByteBuffer.Allocate(size); bitmap.CopyPixelsToBuffer(byteBuffer); byteBuffer.Rewind(); byteBuffer.Get(byteArray); return byteArray; } } public static void AddTemplate(int category, List<int> images) { var templateDB = new TemplateDB(); var imageByteList = new List<byte[]>(); foreach (int image in images) { imageByteList.Add(templateDB.DrawableToByteArray(image)); } var tmpl = new Template() { Category = category, }; var img1 = new TemplateImage() { Category = category, Image = images[0], ImagesHash = DatabaseHelper.GetMD5Hash(imageByteList[0]), }; var img2 = new TemplateImage() { Category = category, Image = images[1], ImagesHash = DatabaseHelper.GetMD5Hash(imageByteList[1]), }; var img3 = new TemplateImage() { Category = category, Image = images[2], ImagesHash = DatabaseHelper.GetMD5Hash(imageByteList[2]), }; var img4 = new TemplateImage() { Category = category, Image = images[3], ImagesHash = DatabaseHelper.GetMD5Hash(imageByteList[3]), }; var img5 = new TemplateImage() { Category = category, Image = images[4], ImagesHash = DatabaseHelper.GetMD5Hash(imageByteList[4]), }; tmpl.TemplateImages = new List<TemplateImage>() { img1, img2, img3, img4, img5 }; tmpl.ImagesHash = DatabaseHelper.GetMD5Hash(ConcatByteList(imageByteList)); var result = DatabaseHelper.db().Query<TemplateImage>("Select * from Templates where ImagesHash=?", tmpl.ImagesHash); if (result.Count == 0) { DatabaseHelper.db().InsertAll(tmpl.TemplateImages); DatabaseHelper.db().Insert(tmpl); DatabaseHelper.db().UpdateWithChildren(tmpl); } }

突然之间,发出内存不足异常。

考虑了一会儿我应该停止编程并开始肚皮舞之后,我认为由于即时通讯在sqlite 

AddTemplate

函数中提供了我必须手动创建的

ResourceIds

的列表(无法避免),那么为什么不给他们我自己的字符串哈希码,然后比较它们以查找记录是否存在?
正确的方法是什么?正在制作将使用“ templates”的Xamarin.Android应用程序,模板是这样的:[Table(“ Templates”)]公共类Template {[PrimaryKey,AutoIncrement] public int Id {... ...>
c# xamarin.android sqlite-net sqlite-net-extensions
1个回答
0
投票
guid作为额外的[[id字段
© www.soinside.com 2019 - 2024. All rights reserved.