ResourceDictionary in Entity Framework Core - lucyberryhub/WPF.Tutorial GitHub Wiki

๐ŸŒŸ ResourceDictionary in Entity Framework Core Without Crashing Migrations

"One day, Lucy Berry was happily coding her WPF application when suddenly... BOOM! โŒ Entity Framework Core threw an error: Object reference not set to an instance of an object. What happened?! ๐Ÿคฏ"

Lucy wanted to store localized strings in Strings.xaml and use them inside her Entity Framework Core database seeding, but when she tried:

Spec = (string)Application.Current.Resources["str_koshou"];

๐Ÿ’ฅ ERROR! ๐Ÿ’ฅ Because EF Core migrations run in a non-WPF environment, Application.Current.Resources is always null.

But fear not! Lucy Berry found the ultimate solution that loads Strings.xaml manually, making EF Core happy! Letโ€™s go step by step. ๐Ÿ†


๐Ÿšจ The Big Problem: Why Canโ€™t EF Core Use Application.Current.Resources?

๐Ÿ“Œ What happens during add-migration?

  • EF Core creates a DbContext without running WPF.
  • WPF resources (like Strings.xaml) donโ€™t exist in this environment.
  • Application.Current is null, so accessing Application.Current.Resources crashes the app!

๐Ÿ”ด The Bad Code That Causes the Crash

Spec = (string)Application.Current.Resources["str_koshou"]; // โŒ Crash! Application.Current is null!

โœ… The Solution: Load Strings.xaml Manually!

๐Ÿ”น Step 1: Create a ResourceHelper to Load Strings.xaml

Lucy created a special helper class that loads the Strings.xaml file manually, even when WPF isnโ€™t running.

๐Ÿ“Œ ResourceHelper.cs

using System;
using System.IO;
using System.Windows;
using System.Windows.Markup;

public static class ResourceHelper
{
    private static ResourceDictionary _resourceDictionary;

    static ResourceHelper()
    {
        LoadResourceDictionary();
    }

    private static void LoadResourceDictionary()
    {
        try
        {
            // Path to your Strings.xaml file (Update this if needed)
            string resourcePath = "Fw/Resources/Strings.xaml"; 

            using (FileStream fs = new FileStream(resourcePath, FileMode.Open, FileAccess.Read))
            {
                _resourceDictionary = (ResourceDictionary)XamlReader.Load(fs);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("โŒ Failed to load Strings.xaml: " + ex.Message);
        }
    }

    public static string GetString(string key)
    {
        if (_resourceDictionary != null && _resourceDictionary.Contains(key))
        {
            return _resourceDictionary[key] as string;
        }

        return key; // ๐Ÿ”„ Fallback to key if not found
    }
}

What this code does:
โœ… Loads Strings.xaml manually so it can be accessed anywhere!
โœ… Uses XamlReader.Load() to parse the .xaml file.
โœ… Falls back to the key if the resource isnโ€™t found.


๐Ÿ”น Step 2: Use ResourceHelper in AppDbContext

Now, Lucy updated AppDbContext.cs to use ResourceHelper.GetString(...) instead of Application.Current.Resources.

๐Ÿ“Œ AppDbContext.cs

modelBuilder.Entity<EnvObikiModel>(entity =>
{
    entity.HasData(
        new EnvObikiModel
        {
            Id = 1,
            Title = "90่ง’ 4m",
            Spec = ResourceHelper.GetString("str_koshou"), // โœ… Works in EF Core migrations!
            ComboValue = "็Ÿฉๅฝข",
            Dim1 = 90,
            Dim2 = 90,
            Dim3 = 4000,
            Deleteable = 0
        }
    );
});

๐ŸŽ‰ Success! Now Strings.xaml can be used inside EF Core migrations without crashing! ๐Ÿš€


๐ŸŽญ Story Time: Lucy Berry and the Magic Strings!

Lucy was working on FwCAD, an amazing WPF application that needed localized text inside an SQLite database. She added all her Japanese labels in Strings.xaml:

<sys:String x:Key="str_koshou">ๅ‘ผ็งฐ</sys:String>
<sys:String x:Key="str_kankyosette">็’ฐๅขƒ่จญๅฎš</sys:String>
<sys:String x:Key="str_kiso">ๅŸบ็คŽ</sys:String>

Then she tried to insert these values into her database using Application.Current.Resources. But when she ran:

dotnet ef migrations add InitialCreate

๐Ÿ’ฅ BOOM! CRASH! ERROR! โŒ

Lucy was sad. ๐Ÿ˜ข But she didnโ€™t give up! ๐Ÿ’ช She found a way to manually load Strings.xaml and made EF Core work with localized text. Now her app can store ๅ‘ผ็งฐ (Koshou) inside the database and retrieve it later! ๐ŸŽ‰


๐Ÿ”น More Example Code

Lucy wanted to make sure other developers could also fetch localized text anywhere in the app. So she wrote more examples:

โœ… Use Localized Strings Anywhere in WPF

string title = ResourceHelper.GetString("str_kankyosette"); // Returns ็’ฐๅขƒ่จญๅฎš
Console.WriteLine(title);

โœ… Use Localized Strings in Data Binding

<TextBlock Text="{x:Static local:ResourceHelper.GetString('str_kiso')}" />

โœ… Use Localized Strings in ViewModel

public string Title => ResourceHelper.GetString("str_kankyosette");

๐Ÿ“Œ Summary: What Lucy Berry Learned

โœ… EF Core migrations run without WPF, so Application.Current.Resources is null.
โœ… Strings.xaml must be loaded manually using XamlReader.Load().
โœ… A helper class (ResourceHelper.cs) makes localized text available inside EF Core and WPF.
โœ… This solution allows localization in the database without breaking migrations!


๐Ÿš€ The Final Victory!

Lucy Berry ran the migration again:

dotnet ef migrations add InitialCreate
dotnet ef database update

โœ… No more errors!
โœ… Localized text is stored in the database!
โœ… Lucy is now an EF Core Localization Champion! ๐Ÿ†๐ŸŽ‰


๐Ÿ‘ฉโ€๐Ÿ’ป Want More?

๐Ÿ“– Read more about ResourceDictionary in WPF: Microsoft Docs
๐Ÿ“– Learn about Entity Framework Core Migrations: EF Core Docs