In Which @Captain asks C# Beginner Questions
-
@fbmac I started with Haskell in 2007, and used it professionally from 2009 to late 2015. Now I just hobby about with it.
Also, I started with imperative/OO languages in 2005 and was fed up with imperative programming by 2006...
-
@Captain said in In Which @Captain asks C# Beginner Questions:
I guess maybe what I'm asking about is a bit ambiguous. I don't want to have to deploy the SQL file when I deploy the application, but have the SQL query compiled into the program
You want it compiled into the exe/dll? I think the only way to do that would be to have it within a class. Maybe an object with an overridden ToString().
Seems a horrible and hacky way to do it. If you have a big load of sql to execute that should be the database's problem somehow. Does it not have any sort of programmability?
Another nasty solution would be to store the sql in a table and execute it with dynamic sql
-
@Captain said in In Which @Captain asks C# Beginner Questions:
I guess maybe what I'm asking about is a bit ambiguous. I don't want to have to deploy the SQL file when I deploy the application, but have the SQL query compiled into the program.
Whoops, missed this requirement.
Eww.
-
@error but @Captain said he didn't want to also have to deploy the file. I think he wants to include the file in his project as an embedded resource.
var resource = "MyProject.Resouces.foo.sql"; var assembly = Assembly.GetExecutingAssembly(); var s = assembly.GetManifestResourceStream(resource); using (var sr = new StreamReader(s)) { // yadda yadda }
-
@Jaloopa said in In Which @Captain asks C# Beginner Questions:
Another nasty solution would be to store the sql in a table and execute it with dynamic sql
What? No. Just. Just no.
Filed under: Where would you store the query to query the queries out of the query table?
-
@NedFodder Yes, missed that clarification as it came while I was already writing the code.
-
@Captain said in In Which @Captain asks C# Beginner Questions:
OK, here's another question. I have a Visual Studio C# project, and I have a long database query in my Program.cs file, saved to a string variable. Is there any way I can put the query in a separate file and just read the contents of that file into a variable?
Yeah; you can put it in the project and set the file type to "embedded resource". There's a quick 2-liner to read that into a stream where you can do whatever with it.
-
@Jaloopa said in In Which @Captain asks C# Beginner Questions:
You want it compiled into the exe/dll? I think the only way to do that would be to have it within a class. Maybe an object with an overridden ToString().
Nope nope nope nope nope, use embedded resource, that's what it's for.
-
@error said in In Which @Captain asks C# Beginner Questions:
What? No. Just. Just no
I can't help it if my mind immediately goes to the most horrible solution I can imagine. I usually manage to avoid committing them to code.
Except the time I had a dead week and decided to implement fibonnaci in as many awful ways as I could
-
@blakeyrat said in In Which @Captain asks C# Beginner Questions:
, use embedded resource, that's what it's for.
Good point. I have used embedded resources before, but rarely so it didn't occur to me
-
@Jaloopa said in In Which @Captain asks C# Beginner Questions:
@error said in In Which @Captain asks C# Beginner Questions:
What? No. Just. Just no
I can't help it if my mind immediately goes to the most horrible solution I can imagine. I usually manage to avoid committing them to code.
Except the time I had a dead week and decided to implement fibonnaci in as many awful ways as I could
The problem with jokes like that (especially in a help forum) is that somebody is going to do it.
-
@Jaloopa Here's the code required:
Assembly _assembly; StreamReader _textStreamReader; try { _assembly = Assembly.GetExecutingAssembly(); _textStreamReader = new StreamReader(_assembly.GetManifestResourceStream("MyNamespace.MyTextFile.txt")); } catch { MessageBox.Show("Error accessing resources!"); }
Quick and dirty copied from StackOverflow, I'm too lazy to open up one of my own projects and see what they look like. No guarantees this is the best way.
EDIT: you can also use a .resx file, but I'm not sure that's cross-platform. So fair warning.
-
Stack Overfill says to embed the query as a resource to get it "effectively" compiled into the executable.
Oops, d
-
@blakeyrat Really? Not closing or disposing the stream? UI code in the error handling?
I thought you advocated for good programs.
-
@error Yes yes Blakeyrat is wrong and stupid at everything, thanks for following me into this thread and critiquing someone else's code to inform me of it.
-
@Jaloopa well the point is that I want to have a .sql file, and have Visual Studio watch it for changes, and not have to deploy the .sql file.
That said, this could be premature optimization, because I have no idea how to deploy an app on windows...
-
@blakeyrat You're giving a newbie bad code, and you don't expect him to use it? I don't care if you wrote it; you're proliferating it.
-
@error I guess I'm just to retardedly dumb to know any better. Better pile-on for another 40-50 posts, in case I haven't gotten the point yet.
-
@blakeyrat said in In Which @Captain asks C# Beginner Questions:
following me into this thread
Also, I was the first responder to this thread, so if anything, you followed me in here.
-
Now now girls
-
@Captain said in In Which @Captain asks C# Beginner Questions:
@Jaloopa well the point is that I want to have a .sql file, and have Visual Studio watch it for changes, and not have to deploy the .sql file.
If you want it to change, you don't want to embed it.
@Captain said in In Which @Captain asks C# Beginner Questions:
That said, this could be premature optimization, because I have no idea how to deploy an app on windows...
"deploy"? You mean like 'put somewhere'? However you want, really. You could just put the assembly and the sql file in the same folder...
-
@error said in In Which @Captain asks C# Beginner Questions:
Here's reading the file:
string query; using( var sr = new StreamReader( @"foo.sql", Encoding.UTF8 ) ) { query = sr.ReadToEnd(); sr.Close(); }
Explicit closing of the reader in a
using
context? Hmmm…
-
@dkf Ofc.
using
just calls Dispose. If the thing also needs to be.Close()
ed, it isn't enough.
-
-
@Magus Disposing an open reader doesn't automatically close it? That's an invitation to resource leakage troubles, so much so that I really suspect that you're wrong.…
-
@dkf See above
-
@asdf Good. But only Dispose is part of the interface, so you have no guarantee of what it is or will be used for.
@dkf said in In Which @Captain asks C# Beginner Questions:
@Magus Disposing an open reader doesn't automatically close it? That's an invitation to resource leakage troubles, so much so that I really suspect that you're wrong.…
If it doesn't, it should; but only Dispose is called by the statement directly. That's all I'm saying.
The .NET devs are good, and don't let these slip by for the most part.
-
@dkf said in In Which @Captain asks C# Beginner Questions:
@error said in In Which @Captain asks C# Beginner Questions:
Here's reading the file:
string query; using( var sr = new StreamReader( @"foo.sql", Encoding.UTF8 ) ) { query = sr.ReadToEnd(); sr.Close(); }
Explicit closing of the reader in a
using
context? Hmmm…It's true that the
StreamReader
class closes the stream implicitly. This is, however, an implementation detail. Two contracts are in play here: "close streams you open" and "dispose resources you allocate." I honor both of them.
-
@error said in In Which @Captain asks C# Beginner Questions:
@dkf said in In Which @Captain asks C# Beginner Questions:
@error said in In Which @Captain asks C# Beginner Questions:
Here's reading the file:
string query; using( var sr = new StreamReader( @"foo.sql", Encoding.UTF8 ) ) { query = sr.ReadToEnd(); sr.Close(); }
Explicit closing of the reader in a
using
context? Hmmm…It's true that the
StreamReader
class closes the stream implicitly. This is, however, an implementation detail. Two contracts are in play here: "close streams you open" and "dispose resources you allocate." I honor both of them.If by "implicitly" you mean "explicitly documented to do so":
MSDN:
Dispose(Boolean)
Closes the underlying stream, releases the unmanaged resources used by the StreamReader, and optionally releases the managed resources.(Overrides TextReader.Dispose(Boolean).)
-
Nobody is perfect. Less pedantry and more halping @Captain pls.
-
@Captain said in In Which @Captain asks C# Beginner Questions:
Nobody is perfect. Less pedantry and more halping @Captain pls.
Apologies. Unfortunately I have nothing further to add beyond what has already been said on your current question.
-
@Captain said in In Which @Captain asks C# Beginner Questions:
That said, this could be premature optimization, because I have no idea how to deploy an app on windows...
Depends on what you mean by deploy, at what scale, and the complexity of the application. It can be as simple as a ZIP file with executable(s), DLL(s) and config file(s) or as complex as multiple MSIs bootstrapped with a C/C++ executable that chains the MSI transactions.
Something something building an MSI with just Microsoft tooling/documentation is like looking at an Elder God/Old One something something FTAH'N
CUTHULUMICROSOFT something something.
-
@Dreikin no worries, it wasn't meant at anybody in particular (and thank you for contributions)
@MathNerdCNU If I was doing this on Linux/Haskell, it would be a single binary executable and cron job. Something on the level of complexity of a folder and cron job would be okay.
But... I don't know how "current working directories" and relative paths and so on work in Windows (which makes me nervous about pushing out a directory instead of a self-contained executable).
-
@Captain You can ask an executable where it's executing from, and relative paths work fine? Especially UNC paths?
-
@Magus well I mean, how does my project relate to my relative path? If I put my
mots.sql
file in the project root, and the executable opens./mots.sql
, will it get the file or blow up at runtime?Or do I explicitly have to set something up?
-
@Captain If you want to do relative to the executing .NET process one of the Assembly static methods can get the path of the executing module and then you can work from there. I can't remember the code off my head and am too lazy to google for it but "Get executing assembly location" in google should point you in right direction. Also, System.IO.Path and System.IO.DirectoryInfo are your friends.
-
@Captain You can explicitly ask for directories from the Assembly, by doing
typeof(Program).Assembly.<whateverman>
-
@error if the only used resource is memory it's ok to not close or dispose it.
it's important for things you want to free asap like db connections and sockets and files in disk
-
@Captain
Path.Combine(Application.StartupPath, "mots.sql")
-
@Captain said in In Which @Captain asks C# Beginner Questions:
well I mean, how does my project relate to my relative path? If I put my mots.sql file in the project root, and the executable opens ./mots.sql, will it get the file or blow up at runtime?
You have to ask the OS/framework what path your executable is running from; don't count on the current working directory to be the same directory your executable is located in, or even the one it was executed from.
EDIT: keep in mind your application under normal circumstances will be in a directory the user doesn't have permissions to write to. It also could be on a network drive.
-
@error YOU SHOULD USE STRINGBUILDER!!!!!!!1111
-
@kt_ Well, you should if you're joining the lines in memory, though the calling function isn't shown here.
-
@Captain this is potentially very dangerous, I would use prepared statements instead with ADO.NET.
You can use the Dapper .NET library which will give you a nice-ish abstraction over the top of ADO.NET.
-
@Magus Dispose() should call Close() unless there was a fucking moron writing the implementation of IDisposable, otherwise there is no point in using the syntactic sugar of the using keyword.
-
@lucas1 I'm already using Dapper.
-
@Captain said in In Which @Captain asks C# Beginner Questions:
I want to have a .sql file, and have Visual Studio watch it for changes, and not have to deploy the .sql file.
Bobby Tables would be very interested.
-
@lolwhat If the file's an embedded resource, all you need to do is sign your app and it can't get altered.
-
@blakeyrat You're right, I misread it.
-
@Captain That is good, it is rather excellent.
-
@Captain said in In Which @Captain asks C# Beginner Questions:
@Magus well I mean, how does my project relate to my relative path? If I put my mots.sql file in the project root, and the executable opens ./mots.sql, will it get the file or blow up at runtime?
It's pretty much the same as on Unix. You really can't count on what your current directory is, and you had better not change it until you've made any user-supplied paths absolute. For coupled resources, you can do things like getting the full name of the executable; some searching indicates that you might use this:
System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName
Embedding the resources within the file is good too, but flexibility is a bit reduced. Or if you're doing proper installations, there's also the option to store key locations of things in the registry.
[EDIT]: Bleah; nodeBB weird updating problems