GVKun编程网logo

SQLite:ON DELETE CASCADE的性能不佳

13

想了解SQLite:ONDELETECASCADE的性能不佳的新动态吗?本文将为您提供详细的信息,此外,我们还将为您介绍关于asp.net-mvc-3–设置表级别WillCascadeOnDelete

想了解SQLite:ON DELETE CASCADE的性能不佳的新动态吗?本文将为您提供详细的信息,此外,我们还将为您介绍关于asp.net-mvc-3 – 设置表级别WillCascadeOnDelete不可用、c# – SQLite在多用户本地网络环境中的性能不佳问题、c# – 实体框架核心,DELETE CASCADE和[必需]、Hibernate:CascadeType.PERSIST不起作用,但是用CascadeType.ALL保存对象的新知识。

本文目录一览:

SQLite:ON DELETE CASCADE的性能不佳

SQLite:ON DELETE CASCADE的性能不佳

我在应用程序中使用SQLite数据库存储测量数据。

它是在项目中分组组织的。这些表与ON DELETE CASCADE用于处理链接的外键互连。该数据库如下所示:

  • 表项目
  • 表组(外键:project_id)
  • 表文件(外键:group_id)
  • 表数据点(外键:file_id)

所有外键引用列的声明如下

project_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT

外键这样声明

FOREIGN KEY(project_id) REFERENCES Projects(project_id) ON DELETE CASCADE

现在,我有1个项目,该项目中有1个组,该组中有800个文件,每个文件约有60个数据点。

删除群组的方法DELETE FROM Groups WHERE project_id=1效果很好,但大约需要21秒,对于我的需求而言,这太长了。

我已将删除内容包装在交易中。

我是SQL和SQLite的极端新手。这个持续时间是正常的还是有什么办法可以加快速度?我需要删除组以填写更新的值。在我的应用程序中,我只想在内存中保留一个项目,因此,仅删除整个数据库并从头开始填充它(虽然速度更快,大约需要1秒),实际上不是一个选择。

这些表是这样创建的:

'Create projects table
cmd.CommandText = "CREATE TABLE IF NOT EXISTS Projects ( ProjectID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT," & _
        "name TEXT NOT NULL,comment TEXT,date DATETIME2,diameter FLOAT(53),thickness FLOAT(53) );"

'Create Groups table
cmd.CommandText &= vbNewline & "CREATE TABLE IF NOT EXISTS Groups ( GroupID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,project_id INTEGER NOT NULL,text TEXT NOT NULL,fixed TINYINT NOT NULL," & _
        "FOREIGN KEY(project_id) REFERENCES Projects(ProjectID) ON DELETE CASCADE );"

asp.net-mvc-3 – 设置表级别WillCascadeOnDelete不可用

asp.net-mvc-3 – 设置表级别WillCascadeOnDelete不可用

我在这里拉出我的头发.我在这里看到了关闭删除级联的解决方案,但我无法实现它.我不知道我在这里做错了什么,但我一直得到以下错误:

‘System.Data.Entity.ModelConfiguration.EntityTypeConfiguration’不包含’WillCascadeOnDelete’的定义,并且没有扩展方法’WillCascadeOnDelete’接受类型’System.Data.Entity.ModelConfiguration.EntityTypeConfiguration’的第一个参数可以找到(你是吗?)缺少using指令或程序集引用?)

我已经添加了必要的命名空间,但我不认为它是intellisense中的任何选项,我没有在任何地方搜索.我在VS 2010 MVC 3中

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using vf2.Models;
using vf2.Models.LinkTables;
using vf2.Models.Requests;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Data.Entity.ModelConfiguration.Configuration;
using System.Data.Entity.ModelConfiguration;
using vf2.Models.Reporting;
using vf2.Models.POSObj;

namespace vf2.Models
{
    public class vfContext : DbContext
    {
        public DbSet<App> Apps { get; set; }
        public DbSet<Origin> Origins { get; set; }
        public DbSet<WineType> WineTypes { get; set; }
        public DbSet<VarType> VarTypes { get; set; }
        public DbSet<Wine> Wines { get; set; }
        public DbSet<Vintage> Vintages { get; set; }

        public DbSet<distributor> distributors { get; set; }
        public DbSet<Importer> Importers { get; set; }
        public DbSet<Producer> Producers { get; set; }
        public DbSet<Publication> Publications { get; set; }
        public DbSet<Review> Reviews { get; set; }
        public DbSet<UserType> UserTypes { get; set; }
        public DbSet<Restaurant> Restaurants { get; set; }

        public DbSet<WineListChangeRate> WineListChangeRates { get; set; }
        public DbSet<MenuChangeRate> MenuChangeRates { get; set; }
        public DbSet<WineListCount> WineListCounts { get; set; }

        public DbSet<UserObj> UserObjs { get; set; }
        public DbSet<ProducerUser> ProducerUsers { get; set; }
        public DbSet<distributorUser> distributorUsers { get; set; }
        public DbSet<RestaurantUser> RestaurantUsers { get; set; }

        public DbSet<ProducerEditRequest> ProducerEditRequests { get; set; }
        public DbSet<RequestStatus> RequestStatuses { get; set; }
        public DbSet<VOAVIRequest> VOAVIRequests { get; set; }

        public DbSet<POS> POSs { get; set; }
        public DbSet<Cart> Carts { get; set; }
        public DbSet<FutureUser> FutureUsers { get; set; }
        public DbSet<Doc> Docs { get; set; }
        public DbSet<DocType> DocTypes { get; set; }

        public DbSet<WineVisit> WineVisits { get; set; }


        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {

            modelBuilder.Entity<Review>().WillCascadeOnDelete(false);
//error here!

            base.OnModelCreating(modelBuilder);
        }
    }
}

解决方法

“级联删除”是关系的配置,而不是实体/表的配置.因此,WillCascadeOnDelete是CascadableNavigationPropertyConfiguration的方法.用例示例:

modelBuilder.Entity<Review>()
    .Hasrequired(r => r.Wine)
    .WithMany()
    .WillCascadeOnDelete(false);

这意味着如果从数据库中的目录中删除葡萄酒,则不应将其评论与葡萄酒一起删除.这是这种特定关系的属性,而不是评论表的属性.

在这种情况下,尝试删除具有评论的葡萄酒会导致外键约束违规和当然例外,但这是您在所需关系上禁用级联删除时通常需要的(“不允许删除葡萄酒”有评论,只允许它没有任何……“)的葡萄酒.

c# – SQLite在多用户本地网络环境中的性能不佳问题

c# – SQLite在多用户本地网络环境中的性能不佳问题

我们在应用程序中使用sqlite作为共享数据库. (我知道这不是最好的解决方案,但服务器/客户端架构是不可能的)
只有少数用户,一个非常小的数据库,只有很少的写入.

该应用程序是用c#编写的,我们使用System.Data.SQLite.dll,但问题也出现在例如SQLiteDatabaseBrowser上

只要只有一个用户连接到数据库并查询某些结果,它就会非常快.只有几毫秒.一个用户可以建立多个连接并并行执行select语句.这对性能也没有影响.

但是,只要来自不同mashine的另一个用户连接到数据库,每个连接用户的性能就会变得非常差.只要所有连接/应用程序都关闭,性能就会很差.
之后,第一个用户连接,获得良好的性能,直到下一个用户连接.

我尝试了很多东西:

> PRAGMA synchronous = OFF
>更新到lates sqlite版本(并使用该版本创建了一个新的db文件)
> DB-File只读
>每个人只读网络共享
>具有不同选项的连接字符串(几乎所有)
>不同的sqlite程序(我们的应用程序和sqliteDatabasebrowser)
>不同的文件系统hostet on(NTFS和fat32)

之后,我写了一个小应用程序,打开一个连接,查询一些结果并显示通过的时间.这一切都在无尽的循环中.

这是这个简单应用程序的代码:

static void Main(string[] args)
    {
        sqliteConnectionStringBuilder conBuilder = new sqliteConnectionStringBuilder();
        conBuilder.DataSource = args[0];
        conBuilder.Pooling = false;                                    
        conBuilder.ReadOnly = true;

        string connectionString = conBuilder.ConnectionString;

        while (true)
        {
            RunQueryInNewConnection(connectionString);
            System.Threading.Thread.Sleep(500);
        }
    }

    static void RunQuery(sqliteConnection con)
    {
        using (sqliteCommand cmd = con.CreateCommand())
        {
            cmd.CommandText = "select * from TabKatalog where ReferenzName like '%0%'";
            Console.WriteLine("Execute Query: " + cmd.CommandText);

            Stopwatch watch = new Stopwatch();
            watch.Start();

            int lines = 0;
            sqliteDataReader reader = cmd.ExecuteReader();
            while (reader.Read())
                lines++;

            watch.Stop();
            Console.WriteLine("Query result: " + lines + " in " + watch.ElapsedMilliseconds + " ms");
        }
    }


    static void RunQueryInNewConnection(string pConnectionString)
    {
        using (sqliteConnection con = new sqliteConnection(pConnectionString,true))
        {
            con.open();
            RunQuery(con);
        }

        System.Data.sqlite.sqliteConnection.ClearallPools();
        GC.Collect();
        GC.WaitForPendingFinalizers();           
    }

在使用这个小应用程序进行测试时,我意识到,只要让另一个系统在sqlite db上获取文件句柄就可以降低性能.所以看来,这与db的连接无关.性能保持低,直到释放所有文件句柄.我用procexp.exe跟踪它.此外,只有远程系统遇到性能问题.在db文件主机本身上,每次查询都会快速运行.

有没有人遇到同样的问题或有一些提示?

解决方法

Windows不会缓存在另一台计算机上同时访问的文件.

如果您需要高并发性,请考虑using a client/server database.

c# – 实体框架核心,DELETE CASCADE和[必需]

c# – 实体框架核心,DELETE CASCADE和[必需]

我遇到了Entity Framework Core中的问题DELETE CASCADE,我似乎无法找到一个好的解决方案.

这是我的模型的超简化版本:

User {UserID,Name}
Recipe {RecipeID,UserID}
Ingredient {IngredientID,UserID}
RecipeIngredient {RecipeID,IngredientID} *RecipeIngredient is the many-to-many table.

配方和成分都将UserID标记为[required],RecipeIngredient将RecipeID和IngredientID标记为[required].

问题是sql不会创建数据库,因为RecipeIngredient有多个级联删除路径(“引入FOREIGN KEY约束……可能导致循环或多个级联路径”).

所以我被困了……我已经完成了一些想法,但没有任何方法可行.

>这里有设计方案吗?我想保留我的外键,因为它是有意义的强制执行它,但如果有一个设计解决方案,我愿意接受它.
>我的下一个想法是删除指向用户的所有FK – 我必须通过我的C#代码在DELETE期间强制执行参照完整性,并且我可以在CREATE期间使用[required]强制执行数据输入.问题 – [必需]创建一个FK,并添加“ON DELETE CASCADE”,这使我们回到多个级联删除路径问题.我真的想保留[必需]因为与Razor页面的光滑集成,客户端验证和错误等.
>接下来的想法,在OnModelCreating(…)中将级联行为设置为SetNull:

modelBuilder.Entity().
    HasOne(i => i.User)
    .WithMany(u => u.Ingredients)
    .OnDelete(DeleteBehavior.SetNull);

modelBuilder.Entity()
    .HasOne(r => r.source)
    .WithMany(s => s.Recipes)
    .OnDelete(DeleteBehavior.SetNull);

但这引发了异常,因为即使我在Ingredient and Recipe中的属性设置为Nullable:

[required(ErrorMessage = "User ID is required.")] 
public Nullable<int> UserID { get; set; }

…由于[required]属性,EF仍然将其创建为NOT NULL数据库列.

这是什么解决方案?据我所知,我应该删除所有FK到User,并尝试将其强制执行为CREATE中的必填字段,但我没有看到使用数据注释的方法,我想做将此逻辑保留在我的代码第一个模型中.

解决方法

我建议禁用级联删除,因为通常开发人员要非常小心删除哪些数据,并且禁用将使您在删除数据时对数据进行更细粒度的控制.

您可以在Context.cs类中的OnModelCreation(DbModelBuilder模型构建器)覆盖中执行以下操作:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
  base.OnModelCreating(modelBuilder);

  modelBuilder.Conventions.Remove<OnetoManyCascadeDeleteConvention>();
  modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
}

在EF Core中,Conventions类不可用,因此您需要遍历实体类型并限制删除以实现所需的效果:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
  base.OnModelCreating(modelBuilder);

  foreach (var relationship in builder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
  {
        relationship.DeleteBehavior = DeleteBehavior.Restrict;
  }
}

Hibernate:CascadeType.PERSIST不起作用,但是用CascadeType.ALL保存对象

Hibernate:CascadeType.PERSIST不起作用,但是用CascadeType.ALL保存对象

如何解决Hibernate:CascadeType.PERSIST不起作用,但是用CascadeType.ALL保存对象?

对于save()要级联的操作,您需要CascadeType.SAVE_UPDATE使用专有的HibernateCascade注释启用,因为save()不是标准的JPA操作。或者您需要使用persist()方法,而不是save()方法。

解决方法

@Entity
@Table(name = “Section_INST”)
public class Section {

@javax.persistence.Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "Section_ID_GENERATOR")
@SequenceGenerator(name = "Section_ID_GENERATOR",sequenceName = "Section_ID_SEQUENCER",initialValue = 1,allocationSize = 1)
@Column(name = "Section_ID")
private int Id;

@Column(name = "Section_Name")
private String name;

@OneToOne(optional = false,cascade = CascadeType.PERSIST)
@JoinColumn(name = "Exch_ID")
private Exchange exchange;

//---Constructor and Getter Setters-----
}


@Entity
@Table(name = "EXCHANGE_INST")
public class Exchange {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "Exchange_ID_GENERATOR")
@SequenceGenerator(name = "Exchange_ID_GENERATOR",sequenceName = "Exchange_ID_SEQUENCER",allocationSize = 1)
@Column(name = "Exchange_ID")
private int Id;

@Column(name = "Exchange_name")
private String name;

@OneToOne(mappedBy ="exchange")
private Section section;

//-----------Getter and Setter...And Constructor

}

以下程序不起作用->

    final SessionFactory sessionFactory = configuration.buildSessionFactory();
    final Session session = sessionFactory.openSession();
    session.beginTransaction();

    final Exchange exchange = new Exchange("MyExchange");
    final Section section = new Section("MySection",exchange);
    exchange.setSection(section);
    session.save(section);

    session.getTransaction().commit();
    session.close();

如果我将Section.java中的层叠选项更改为CascadeType.ALL,那么它将起作用。

@OneToOne(optional = false,cascade = CascadeType.PERSIST)   --- > CascadeType.ALL 
@JoinColumn(name = "Exch_ID")
private Exchange exchange;

我认为PERSIST应该保存我的对象d =,但是会引发异常:

org.hibernate.TransientPropertyValueException:非null属性引用一个瞬态值-
必须在当前操作之前保存瞬态实例:Section.exchange-> Exchange

今天关于SQLite:ON DELETE CASCADE的性能不佳的讲解已经结束,谢谢您的阅读,如果想了解更多关于asp.net-mvc-3 – 设置表级别WillCascadeOnDelete不可用、c# – SQLite在多用户本地网络环境中的性能不佳问题、c# – 实体框架核心,DELETE CASCADE和[必需]、Hibernate:CascadeType.PERSIST不起作用,但是用CascadeType.ALL保存对象的相关知识,请在本站搜索。

本文标签: