Jak poprawnie za pomocą Entity Frameworka przechowywać dane między kolejnymi startami aplikacji

0

Mam małą aplikację w WinFormsach, która umożliwia użytkownikowi dodawanie/edycję/usuwanie rekordów w lokalnej bazie danych. Mam problem z poprawną obsługą danych między kolejnymi startami aplikacji. Obecnie za każdym odpaleniem aplikacji tworzę nową bazę i wypełniam ją przykładowymi danymi. Chciałbym jednak, żeby aplikacja cały czas działała na jednej bazie, tzn, żeby wszystkie zmiany były zapisywane. Niestety nie wiem jak to osiągnąć. Klasa odpowiedzialna za wypełnienie przykładowymi danymi:

public class ExampleDataFiller
{
    public BloodBankContext bloodBankContext;
    public List<BloodDonor> ExampleDonators;
    public ExampleDataFiller (BloodBankContext bloodBankContext)
    {
        this.bloodBankContext = bloodBankContext;
        ExampleDonators=new List<BloodDonor>();


        BloodDonor bloodDonor1 = new BloodDonor()
        {
            FirstName="Marcus",
            LastName="Wilkins",
            DateofBirth=new DateTime(1960, 10, 27),
            DateOfRegistration=DateTime.Now,
            BloodType=BloodTypes.ABRHminus,


        };
        ExampleDonators.Add(bloodDonor1);

        BloodDonor bloodDonor2 = new BloodDonor()
        {
            FirstName = "Raul",
            LastName = "Davies",
            DateofBirth = new DateTime(1958, 08, 26),
            DateOfRegistration = DateTime.Now,
            BloodType = BloodTypes.ARHminus,


        };
        ExampleDonators.Add(bloodDonor2);

        BloodDonor bloodDonor3 = new BloodDonor()
        {
            FirstName = "Richard",
            LastName = "Lance",
            DateofBirth = new DateTime(1981, 07, 02),
            DateOfRegistration = DateTime.Now,
            BloodType = BloodTypes.ORHplus,


        };
        ExampleDonators.Add(bloodDonor3);

        BloodDonor bloodDonor4 = new BloodDonor()
        {
            FirstName = "Leonard",
            LastName = "Spencer",
            DateofBirth = new DateTime(1955, 06, 03),
            DateOfRegistration = DateTime.Now,
            BloodType = BloodTypes.ARHplus,


        };
        ExampleDonators.Add(bloodDonor4);

        BloodDonor bloodDonor5 = new BloodDonor()
        {
            FirstName = "Jennifer",
            LastName = "Hays",
            DateofBirth = new DateTime(1960, 01, 13),
            DateOfRegistration = DateTime.Now,
            BloodType = BloodTypes.ARHplus,


        };
        ExampleDonators.Add(bloodDonor5);

        foreach (var donor in ExampleDonators)
        {
            bloodBankContext.BloodDonors.Add(donor);
            bloodBankContext.SaveChanges();
        }

    }


} 

Moja klasa dziedzicząca po DbContext:

public class BloodBankContext: DbContext
{
    public BloodBankContext() : base("BloodBankDatabase1") 
    {
        Database.SetInitializer<BloodBankContext>(new DropCreateDatabaseAlways<BloodBankContext>());
    }
    public DbSet<BloodDonor> BloodDonors { get; set; }
    public DbSet<BloodDonation> BloodDonations { get; set; }
    public DbSet<StoredBlood> storedBlood { get; set; }    
} 

Utworzenie bazy, wypełnienie przykładowymi danymi i wyświetlenie:

public partial class BloodBankManager : Form
{
    public static BloodBankContext context;
    public BloodBankManager()
    {
        InitializeComponent();
        context = new BloodBankContext();
        ExampleDataFiller exampleDataFiller = new ExampleDataFiller(context);
        dataGridView1.DataSource = context.BloodDonors.Local.ToBindingList();

        comboBox1.DataSource = Enum.GetValues(typeof(BloodTypes));

    }
} 

Kombinowałem z dwoma innymi initializerami, jak również napisałem swój własny, jednak nie potrafię osiągnąć tego co chcę.

Podsumowując: jak za pomocą Entity Frameworka poprawnie przechowywać dane pomiędzy kolejnymi startami aplikacji?

0

Podsumowując: jak za pomocą Entity Frameworka poprawnie przechowywać dane pomiędzy kolejnymi startami aplikacji?

To już powinno poprawnie przechowywać dane. Ta baza to jest jakieś LocalDB? Sprawdź czy plik bazy .mdf (czy co tam innego jest) w properties nie ma ustawionego 'Copy always'

0
dam1an napisał(a):

To już powinno poprawnie przechowywać dane. Ta baza to jest jakieś LocalDB? Sprawdź czy plik bazy .mdf (czy co tam innego jest) w properties nie ma ustawionego 'Copy always'

Tak, to jest LocalDB. Żadnej takiej właściwości nie widzę.

0

ppm na plik .mdf - properties - Copy to output directory(czy coś w tym stylu), i tu ustaw Copy if newer

0

Wg mnie niepotrzebna jest inicjacja tworzenia bazy w konstruktorze. Database.SetInitializer<BloodBankContext>(new DropCreateDatabaseAlways<BloodBankContext>()); - (usuwaj i twórz bazę przy każdym odpaleniu aplikacji). Spróbuj tak:

public class BloodBankContext: DbContext
{
    public BloodBankContext() : base("BloodBankDatabase1") 
    {
        
    }
    public DbSet<BloodDonor> BloodDonors { get; set; }
    public DbSet<BloodDonation> BloodDonations { get; set; }
    public DbSet<StoredBlood> storedBlood { get; set; }    
} 
0
public class BloodBankContext: DbContext
{
    public BloodBankContext() : base("BloodBankDatabase1") 
    {
          Database.SetInitializer<BloodBankContext>(new CreateDatabaseIfNotExists<BloodBankContext>()); // Domyślna inicjalizacja
          // Database.SetInitializer<BloodBankContext>(new DropCreateDatabaseIfModelChanges<BloodBankContext>()); // Nowa baza jeśli zmienił się model
          // Database.SetInitializer<BloodBankContext>(new DropCreateDatabaseAlways<BloodBankContext>()); // Zawsze utworzy nową bazę
          // Możesz utworzyć własną na przykład dziedzicząc po jednym z powyższych i  wepchnąć tam przykładowe dane
          // Database.SetInitializer<BloodBankContext>(new MojaInizjalizacja<BloodBankContext>()); 
    }
    public DbSet<BloodDonor> BloodDonors { get; set; }
    public DbSet<BloodDonation> BloodDonations { get; set; }
    public DbSet<StoredBlood> storedBlood { get; set; }    
}
public class MojaInizjalizacja:  DropCreateDatabaseIfModelChanges<BloodBankContext>
    {
        protected override void Seed(BloodBankContextcontext)
        {
            base.Seed(context);
            BloodDonor bloodDonor1 = new BloodDonor()
            // ...
        }
    }
} 
0

Dzięki Panowie za odpowiedzi, niestety żadne z zaproponowanych przez Was rozwiązań nie działa :(

dam1an napisał(a):

ppm na plik .mdf - properties - Copy to output directory(czy coś w tym stylu), i tu ustaw Copy if newer

Z poziomu "projektu" nie mam dostępu do tej bazy. Mogę się jedynie połączyć poprzez server explorer, ale tam takiego property nie ma.

@mały Lew @DibbyDum Tych podejść też próbowałem i nie działały niestety.

Tak zaczynam myśleć, że ja chyba w ogóle złe podejście stosuję i przez to się nie rozumiemy do końca :)

Bo czy nie powinienem przypadkiem za pierwszym odpaleniem apki stworzyć bazę, a za każdym kolejnym sprawdzać czy baza istnieje, i jeśli istnieje to wtedy w jakiś inny sposób się do niej podłączać (i to na tej wersji by sobie user pracował). Czyli coś takiego:

if(czyBazaIstnieje) {
    podłączDoBazy();
    }
else {
    BloodBankContext context=new BloodBankContext();
    } 
0

Tak tylko napiszę, może się kiedyś komuś przyda.
Rozwiązanie polegało na konieczności dodania ładowania danych z bazy do lokalnego kontekstu:

context.BloodDonors.Load(); 

Takie proste a co się namęczyłem to moje :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1