Моя таблица будет содержать много повторяющихся строк, таких как домены. Для минимизации размера базы данных я хочу сохранить только уникальные домены в другой таблице и использовать идентификаторы доменов в основной таблице.
Все время я делал это вручную, но недавно я узнал, что SQLite может делать это автоматически.
Теперь я пытаюсь использовать отношения «многие к одному» с ключом «ЧУЖОЙ», но безуспешно. Может я что-то не так делаю.
Пример кода
Классы столов:
public class Domains
{
public Domains() { }
public Domains(string domain) { this.Domain = domain; }
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
[Unique, MaxLength(64)]
public string Domain { get; set; }
}
public class Statistics
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public int Timestamp { get; set; }
[ForeignKey(typeof(Domains))]
public int DomainId { get; set; }
public int Status { get; set; }
[ManyToOne(CascadeOperations = CascadeOperation.All)]
public Domains Domain { get; set; }
}
Основной код:
static void Main(string[] args)
{
var dbFile = "stats.db";
var domains = new[] { "stackoverflow.com", "superuser.com", "serverfault.com", "google.com", "microsoft.com" };
var statList = new List<Statistics>();
var sqlBase = new SQLiteConnection(dbFile);
sqlBase.Execute("PRAGMA foreign_keys = ON");
sqlBase.CreateTable<Domains>();
sqlBase.CreateTable<Statistics>();
Console.WriteLine(SQLite3.LibVersionNumber());
var runTimestamp = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
foreach (var domain in domains)
{
HttpWebResponse resp = null;
var status = -1;
try
{
resp = (HttpWebResponse)WebRequest.Create("http://" + domain).GetResponse();
}
catch { };
status = (int)resp.StatusCode;
var stat = new Statistics();
stat.Domain = new Domains(domain);
stat.Status = status;
stat.Timestamp = runTimestamp;
statList.Add(stat);
}
sqlBase.InsertOrIgnoreAllWithChildren(statList); // Modification "INSERT" with "OR IGNORE"
Console.WriteLine(@"Table ""Domains""");
foreach (var table in sqlBase.Table<Domains>())
{
Console.WriteLine("Id: {0}\tDomain: {1}", table.Id, table.Domain);
}
Console.WriteLine();
Console.WriteLine(@"Table ""Statistics""");
foreach (var table in sqlBase.Table<Statistics>())
{
Console.WriteLine("Id: {0}\tDomain Id: {1}", table.Id, table.DomainId);
}
Console.WriteLine();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
После первого запуска выглядит нормально.
Но после второго запуска, когда домены повторяются - расширения sqlite вставляют неверный идентификатор домена.
Где я ошибаюсь?
InsertOrIgnoreAllWithChildren
? - person redent84   schedule 16.03.2017