Я использую EF для хранения данных в базе данных SQL Server.Хранение коллекции с несколькими одинаковыми элементами
Есть 2 типа данных:
- Image
- Символ
Каждый символ содержит коллекцию изображений
public virtual ICollection<Image> Images { get; set; }
и каждое изображение содержит набор символов :
public virtual ICollection<Symbol> Symbols { get; set; }
EF создает таблицу отношений для отношений «многие-ко-многим».
Если новый символ создан (загружен), программа просматривает таблицу изображений, если эти изображения уже загружены.
Если да, то будет добавлен в список изображений нового символа.
Теперь есть символ с 3 изображениями (все равно!), И он будет добавлен в таблицу Symbols
.
Но в таблице отношений создается ТОЛЬКО ОДИН элемент !?
Так что в следующий раз, когда это Symbol
считывается из базы данных он просто содержит только 1 изображение ...
Что я делаю неправильно?
Или что было бы правильным путем?
Таблица структуры:
[Table("Images")]
public class SqlSymbolImgInfo
{
[Key]
public int Id { get; set; }
public String Path { get; set; }
public long Size { get; set; }
public String Md5 { get; set; }
public int X { get; set; }
public int Y { get; set; }
public virtual ICollection<SqlSymbol> Symbols { get; set; }
public override int GetHashCode()
{
return System.IO.Path.GetExtension(Path ?? "x.png").GetHashCode() + Size.GetHashCode() + (Md5 ?? "").GetHashCode();
}
}
[Table("Symbols")]
public class SqlSymbol
{
[Key]
public int Id { get; set; }
public String Description { get; set; }
public int Type { get; set; }
public virtual ICollection<SqlSymbolImgInfo> Images { get; set; }
}
Создание отношения:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<System.Data.Entity.ModelConfiguration.Conventions.PluralizingTableNameConvention>();
modelBuilder.Entity<SqlSymbol>().HasMany(s => s.Images).WithMany(i => i.Symbols);
base.OnModelCreating(modelBuilder);
}
Добавление символов:
Добавьте изображения, если они п ВЗ существует
Получить добавленные изображения назад
Добавить символ
public void AddSymbol(Symbol sym) { try { using (var db = new Db()) { // check if images already exists or add them.. foreach (var img in sym.Images) { var exImg = db.FindImage(img); if (exImg == null) { var newImg = db.Images.Add(img.ConvertToSqlSymbolImgInfo()); db.SaveChanges(); img.Id = newImg.Id; // get Id of new image } else { img.Id = exImg.Id; // get Id of existing image } } var sqlSym = sym.ConvertToSqlSymbol(); // get the existing entries, otherwise the same image will be added again and again... sqlSym.Images = sym.Images.Select(i => db.Images.Find(i.Id)).ToList(); db.Symbols.Add(sqlSym); db.SaveChanges(); sym.Id = sqlSym; } } catch { logIt("error while adding a symbol."); } }
Для объяснения:
Мне нужно использовать классы-оболочку для рамочной сущности тяжбы Symbol
и Image
классы находятся в общей библиотеке. И я не хочу включать EF во все другие проекты, даже если я его не использую.
Некоторые ДОПОЛНИТЕЛЬНО:
Символ 3 одинаковых изображений:
Коллекция после добавления и "поиск" изображение:
После добавления этого Symbol
в базу данных, посмотрите на таблицы:
Images
стол:
и таблица отношений:
!! отмеченная строка должна быть там 3 раза?!
Его Symbol
с идентификатором 50, который имеет 3 Images
с идентификатором 108. Не только один!
Вот упрощенный проект, чтобы проверить это с помощью всего нескольких строк кода:
Что не так, если у вас есть * одно изображение в базе и несколько копий этого изображения в памяти (при условии, что вы действительно хотите по какой-то причине)? – Tigran
еще несколько деталей: в «Картинке-таблице» представлены все доступные изображения. И у Символов есть только «ссылки» на содержащиеся Изображения .. Так что если есть Символ с несколькими кратными тем же изображением, я не могу его сохранить в данный момент. – mxii
Не могли бы вы показать нам структуру таблиц ** - большинство важная таблица, содержащая многозначное сопоставление между символами и изображениями. –