使用 Entity Framework 4 在运行时打开 SQL CE 文件

发布于 2024-08-25 06:57:24 字数 2411 浏览 3 评论 0原文

我正在开始使用 Entity Framework 4,并创建一个演示应用程序作为学习练习。该应用程序是一个简单的文档生成器,它使用 SQL CE 存储。每个文档项目都有自己的 SQL CE 数据文件,用户打开这些文件之一来处理项目。

EDM 非常简单。文档项目由主题列表组成,每个主题都有标题、描述和零个或多个注释。因此,我的实体是主题,其中包含标题和文本属性,以及注释,其中包含标题和文本属性。从主题到注释存在一对多关联。

我想弄清楚如何打开 SQL CE 数据文件。数据文件必须与 EF4 的创建数据库向导创建的 SQL CE 数据库的架构相匹配,我将在应用程序的其他位置实现一个新文件用例来实现该要求。现在,我只是想在应用程序中打开现有的数据文件。

我在下面复制了现有的“打开文件”代码。我已将其设置为名为文件服务的静态服务类。该代码尚未正常工作,但足以显示我正在尝试做的事情。我试图保持 ObjectContext 打开以进行实体对象更新,并在文件关闭时对其进行处置。

所以,这是我的问题:我走在正确的道路上吗?我需要更改什么才能使此代码与 EF4 兼容?有一个如何正确执行此操作的示例吗?

感谢您的帮助。

我现有的代码:

public static class FileServices
{
    #region Private Fields

    // Member variables
    private static EntityConnection m_EntityConnection;
    private static ObjectContext m_ObjectContext;

    #endregion

    #region Service Methods

    /// <summary>
    /// Opens an SQL CE database file.
    /// </summary>
    /// <param name="filePath">The path to the SQL CE file to open.</param>
    /// <param name="viewModel">The main window view model.</param>
    public static void OpenSqlCeFile(string filePath, MainWindowViewModel viewModel)
    {  
        // Configure an SQL CE connection string
        var sqlCeConnectionString = string.Format("Data Source={0}", filePath);

        // Configure an EDM connection string
        var builder = new EntityConnectionStringBuilder();
        builder.Metadata = "res://*/EF4Model.csdl|res://*/EF4Model.ssdl|res://*/EF4Model.msl";
        builder.Provider = "System.Data.SqlServerCe";
        builder.ProviderConnectionString = sqlCeConnectionString;
        var entityConnectionString = builder.ToString();

        // Connect to the model
        m_EntityConnection = new EntityConnection(entityConnectionString);
        m_EntityConnection.Open();

        // Create an object context
        m_ObjectContext = new Model1Container();

        // Get all Subject data
        IQueryable<Subject> subjects = from s in Subjects orderby s.Title select s;

        // Set view model data property
        viewModel.Subjects = new ObservableCollection<Subject>(subjects);
    }

    /// <summary>
    /// Closes an SQL CE database file.
    /// </summary>
    public static void CloseSqlCeFile()
    {
        m_EntityConnection.Close();
        m_ObjectContext.Dispose();
    }

    #endregion
}

I am getting started with Entity Framework 4, and I an creating a demo app as a learning exercise. The app is a simple documentation builder, and it uses a SQL CE store. Each documentation project has its own SQL CE data file, and the user opens one of these files to work on a project.

The EDM is very simple. A documentation project is comprised of a list of subjects, each of which has a title, a description, and zero or more notes. So, my entities are Subject, which contains Title and Text properties, and Note, which has Title and Text properties. There is a one-to-many association from Subject to Note.

I am trying to figure out how to open an SQL CE data file. A data file must match the schema of the SQL CE database created by EF4's Create Database Wizard, and I will implement a New File use case elsewhere in the app to implement that requirement. Right now, I am just trying to get an existing data file open in the app.

I have reproduced my existing 'Open File' code below. I have set it up as a static service class called File Services. The code isn't working quite yet, but there is enough to show what I am trying to do. I am trying to hold the ObjectContext open for entity object updates, disposing it when the file is closed.

So, here is my question: Am I on the right track? What do I need to change to make this code work with EF4? Is there an example of how to do this properly?

Thanks for your help.

My existing code:

public static class FileServices
{
    #region Private Fields

    // Member variables
    private static EntityConnection m_EntityConnection;
    private static ObjectContext m_ObjectContext;

    #endregion

    #region Service Methods

    /// <summary>
    /// Opens an SQL CE database file.
    /// </summary>
    /// <param name="filePath">The path to the SQL CE file to open.</param>
    /// <param name="viewModel">The main window view model.</param>
    public static void OpenSqlCeFile(string filePath, MainWindowViewModel viewModel)
    {  
        // Configure an SQL CE connection string
        var sqlCeConnectionString = string.Format("Data Source={0}", filePath);

        // Configure an EDM connection string
        var builder = new EntityConnectionStringBuilder();
        builder.Metadata = "res://*/EF4Model.csdl|res://*/EF4Model.ssdl|res://*/EF4Model.msl";
        builder.Provider = "System.Data.SqlServerCe";
        builder.ProviderConnectionString = sqlCeConnectionString;
        var entityConnectionString = builder.ToString();

        // Connect to the model
        m_EntityConnection = new EntityConnection(entityConnectionString);
        m_EntityConnection.Open();

        // Create an object context
        m_ObjectContext = new Model1Container();

        // Get all Subject data
        IQueryable<Subject> subjects = from s in Subjects orderby s.Title select s;

        // Set view model data property
        viewModel.Subjects = new ObservableCollection<Subject>(subjects);
    }

    /// <summary>
    /// Closes an SQL CE database file.
    /// </summary>
    public static void CloseSqlCeFile()
    {
        m_EntityConnection.Close();
        m_ObjectContext.Dispose();
    }

    #endregion
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

倾城泪 2024-09-01 06:57:24

这就是答案。我简化了代码并在更简单的 EDM 模型(迪士尼角色)上运行。模型有两个实体:CharacterChildCharacterChild 之间存在 1:* 关联。孩子就是角色的孩子——很简单的事情。我将演示编写为控制台应用程序,以使其尽可能简单。

Program.cs 中的完整代码如下:

class Program
{
    static void Main(string[] args)
    {
        /* See http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/8a89a728-6c8d-4734-98cb-11b196ba11fd */

        // Configure an SQL CE connection string 
        var filePath = @"D:\Users\dcveeneman\Documents\Visual Studio 2010\Demos\SqlCeEf4Demo\SqlCeEf4Demo\DisneyChars.sdf";
        var sqlCeConnectionString = string.Format("Data Source={0}", filePath);

        // Create an EDM connection
        var builder = new EntityConnectionStringBuilder();
        builder.Metadata = "res://*/DisneyChars.csdl|res://*/DisneyChars.ssdl|res://*/DisneyChars.msl";
        builder.Provider = "System.Data.SqlServerCe.3.5";
        builder.ProviderConnectionString = sqlCeConnectionString;
        var edmConnectionString = builder.ToString();
        var edmConnection = new EntityConnection(edmConnectionString);

        // Build and query an ObjectContext
        using (var context = new DisneyCharsContainer(edmConnection))
        {
            var chars = context.Characters;
            foreach(var character in chars)
            {
                Console.WriteLine("Character name: {0}", character.Name);
                foreach(var child in character.Children)
                {
                    Console.WriteLine("Child name: {0}", child.Name);
                }
            }
            Console.ReadLine();
        }
    }
}

代码顶部的链接是我用来编写代码的论坛帖子。

演练如下:首先,创建数据库连接。由于我使用的是 SQL CE,所以我没有连接字符串生成器——连接字符串只是一个路径,所以我不需要它。然后,我使用 EntityConnectionStringBuilder 构建实体连接字符串,然后使用它构建 EntityConnection。最后,我将连接传递给 ObjectContext 的构造函数。然后,我可以使用 ObjectContext 查询 EDM。

Here is the answer. I simplified my code and ran it on simpler EDM model, Disney Characters. Model has two entities, Character and Child, with a 1:* association between Character and Child. Children are character's kids--pretty simple stuff. I wrote the demo as a console app to keep it as simple as possible.

Complete code in Program.cs is as follows:

class Program
{
    static void Main(string[] args)
    {
        /* See http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/8a89a728-6c8d-4734-98cb-11b196ba11fd */

        // Configure an SQL CE connection string 
        var filePath = @"D:\Users\dcveeneman\Documents\Visual Studio 2010\Demos\SqlCeEf4Demo\SqlCeEf4Demo\DisneyChars.sdf";
        var sqlCeConnectionString = string.Format("Data Source={0}", filePath);

        // Create an EDM connection
        var builder = new EntityConnectionStringBuilder();
        builder.Metadata = "res://*/DisneyChars.csdl|res://*/DisneyChars.ssdl|res://*/DisneyChars.msl";
        builder.Provider = "System.Data.SqlServerCe.3.5";
        builder.ProviderConnectionString = sqlCeConnectionString;
        var edmConnectionString = builder.ToString();
        var edmConnection = new EntityConnection(edmConnectionString);

        // Build and query an ObjectContext
        using (var context = new DisneyCharsContainer(edmConnection))
        {
            var chars = context.Characters;
            foreach(var character in chars)
            {
                Console.WriteLine("Character name: {0}", character.Name);
                foreach(var child in character.Children)
                {
                    Console.WriteLine("Child name: {0}", child.Name);
                }
            }
            Console.ReadLine();
        }
    }
}

Link at the top of the code is to a forum thread that I used to write the code.

Here is the walkthrough: First, create a database connection. Since I am using SQL CE, I don't have a connection string builder--the connection string is simply a path, so I don't need one. Then I use an EntityConnectionStringBuilder to build an entity connection string, and then I use that to build an EntityConnection. Finally, I pass the connection to the constructor for my ObjectContext. I can then use the ObjectContext to query the EDM.

预谋 2024-09-01 06:57:24

由于某些奇怪的原因,查找/打开 SQL Server CE 数据库是 很难做到。在尝试让数据库与 EF 一起工作之前,请确保您可以与数据库建立任何类型的连接。

Finding / opening a SQL Server CE database is, for some weird reason, hard to do. Make sure you can make any kind of connection to the DB at all before trying to get it to work with the EF.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文