3

I'm trying to establish access to an embedded SQL resource file I've created in a Class Library. However, I'm not sure where to go from here.

I've accessed the resource using:

Assembly.GetExcecutingAssembly().GetManifestResourceStream("InsertTest.sql");

My understanding is that there is a way to access them in a strongly typed fashion, but I can't seem to get a handle on the project or the solution to browse through their respective properties or resources programatically.

What am I missing?

4
  • Well, I've accessed the file using Assembly.GetExecutingAssembly().GetManifestResourceStream("InsertTest.sql");, but I can't figure out how to access this in a strongly typed way. Commented Nov 14, 2012 at 17:02
  • There should be a method on the Assembly class that lists the resources. I don't have VS in front of me, but IIRC it's called GetManifestResourceNames() and returns a string[] of all of the embedded resources, with the folder structure of the project (suffixed with the resource name) used as the naming convention. Commented Nov 14, 2012 at 17:07
  • What type would you want to see this as? System.IO.File, or System.String (for the data in the file), etc. Commented Nov 14, 2012 at 17:12
  • I'm pigeon holed into using inline SQL instead of stored procedures, so I'm trying to organize the SQL being used into resources. Ideally, I'd just make a call off to the file being used and it would return a string of it's contents. Commented Nov 14, 2012 at 17:25

3 Answers 3

8

Although I did get some great suggestions (see Philip Daniels' answer - good stuff), none of them really addressed my specific concerns. However, I found that the easiest way to accomplish this was to do the following:

  1. Right click your project and select 'Properties'
  2. Select the 'Resources' tab. Create a new resources file if necessary.
  3. In the upper left hand corner there is a drop down that defaults to 'Strings'. Click this box and choose 'Files'.
  4. Drag and drop the resource file you'd like to embed in the project.

You can now access a strongly typed resource using the following syntax:

Project.Properties.Resources.ResourceName;

In my situation, this worked perfectly as I am storing inline SQL in these files and it returns the sql embedded in the file. Keep in mind, however, that by defaults these resources are linked and not embedded, but you can change their property to set them to embedded.

Hope this helps someone!

Sign up to request clarification or add additional context in comments.

Comments

1

You're almost there. I have a couple of functions I use for this. You can do somehting very similar for images. I'm not sure it's worth creating properties like you want (you can do that through the Resources tab of the project properties if you insist).

/// <summary>
    /// Gets an open stream on the specified embedded resource. It is the
    /// caller's responsibility to call Dispose() on the stream.
    /// The filename is of the format "folder.folder.filename.ext"
    /// and is case sensitive.
    /// </summary>
    /// <param name="assembly">The assembly from which to retrieve the Stream.</param>
    /// <param name="filename">Filename whose contents you want.</param>
    /// <returns>Stream object.</returns>
    public static Stream GetStream(Assembly assembly, string filename)
    {
        string name = String.Concat(assembly.GetName().Name, ".", filename);
        Stream s = assembly.GetManifestResourceStream(name);
        return s;
    }

    /// <summary>
    /// Get the contents of an embedded file as a string.
    /// The filename is of the format "folder.folder.filename.ext"
    /// and is case sensitive.
    /// </summary>
    /// <param name="assembly">The assembly from which to retrieve the file.</param>
    /// <param name="filename">Filename whose contents you want.</param>
    /// <returns>String object.</returns>
    public static string GetFileAsString(Assembly assembly, string filename)
    {
        using (Stream s = GetStream(assembly, filename))
        using (StreamReader sr = new StreamReader(s))
        {
            string fileContents = sr.ReadToEnd();
            return fileContents;
        }
    }

Comments

1

On a resource file you won't be able to have intellisense to build your sql script compare to have them as separate files in your project. You can create a helper class to access them in a strong type fashion:

public class Scripts
{
    public static string Sql1
    {
        get
        {
            return GetResource("sql1.sql");
        }
    }

   public static string Sql2
   {
        get
        {
           return GetResource("sql2.sql");
        }
   }

    private static string GetResource(string name)
    {
        var assembly = Assembly.GetExecutingAssembly();
        using(var stream = new StreamReader(assembly.GetManifestResourceStream("Myproject.Sql." + name)))
        {
            return stream.ReadToEnd();
        }
    }
}

For example, in Dapper, you can access your scripts like this:

using(var db = new SqlConnection("yourconnectionstring")){
    db.Open();
    var results = db.Query(Scripts.Sql1);
} 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.