CS0246 error with OdbcConnection line in C# - c#

Ive been chasing this CS0246 error for a couple hours and am not sure how to resolve it. Given this simple C# code:
using System;
// using Microsoft.Data.Odbc;
using System.Data.Odbc;
namespace dotnetdb
{
class Program
{
static private void SelectRows(string[] args)
{
string passWord = "PWD=password";
string uName = "UID=username";
string dbServer = "SERVER=server";
string dbName = "DATABASE=db";
string driver = "DRIVER={ODBC Driver 13 for SQL Server}"
string connString = // assembled from above
string sql = // sql;
OdbcConnection conn = new OdbcConnection(connString);
conn.Open();
OdbcCommand cmd = new OdbcCommand(sql, conn);
// work with cmd
Console.WriteLine("Didnt kick the bucket!");
}
}
}
The Microsoft stanza on line 2 yields a CS0234 error. The stanza on line 3 (from the Microsoft docs) gives me the CS0246:
Program.cs(20,13): error CS0246: The type or namespace name 'OdbcConnection' could not be found
I use this ODBC connection in go and python all the time but this is my first attempt at using it with C#. Also my first ever C# program. The code above is scraped almost directly from the MS docs - what am I missing? How do I get access to System.Data.Odbc?
Am I trying to run before I learn how to walk with C#?
Note that applications created with dotnet build [console|webapi] build and run just fine.
Thanks!

You need to add it as a reference. Refer to this question on how to add a reference in Visual Studio Code. I also noticed that your program doesn't have a Main() and that'll prevent it from compiling also.
Change this:
static private void SelectRows(string[] args)
to
static void Main(string[] args)
Or call it from Main() like this:
static void Main(string[] args)
{
SelectRows(args);
}
private static void SelectRows(String[] args)
{
...
}
In general references are a piece of compiled code, mostly in .DLL format which you can include in your own project so you can use the methods/code that the reference provides.
For example,
Let's say I have MyMath.dll which was created by somebody and I want to use this method in it.
int Add(int a, int b) {
return a + b;
}
I have to include that MyMath.dll that somebody else created in order to use that Add() method. So when I want to use it, I use something like this.
using MyMath; // MyMath.dll
static void Main(string[] args)
{
MyMath calculator = new MyMath();
int result = calculator.Add(1, 2);
}
If you don't know, Visual Studio has a free community version that's pretty powerful too.

Related

Command Line Parser NUGet Package getting simple example program to work

I'm finding this very challenging and I appreciate any help you are willing of offer me.
Currently I'm trying to implement Command Line Parser (https://github.com/commandlineparser/commandline).
I just want to get a basic example application working and I am stuck.
Ultimately I want the following pattern
MyProgram -soureid 1231 -domain alpha
Where I get sourceid and domain as valid variables. sourceid would have the value of 1231 and domain would have the value of "alpha".
This is a C# .net core application (2.3) and I'm running Visual Studio 2017.
Here is the code that I have so far...
using System;
using CommandLine;
namespace Program
{
class Program
{
public static void Main(String[] args)
{
var options = new SomeOptions();
CommandLine.Parser.Default.ParseArguments(args, typeof(SomeOptions));
Console.WriteLine(options.Age);
Console.ReadLine();
}
}
class SomeOptions
{
[Option('n', "name", Required = true)]
public string Name { get; set; }
[Option('a', "age")]
public int Age { get; set; }
}
}
This code does not work. When I pass -n Jason I get this..
CommandLineArgumentParsing 1.0.0
Copyright (C) 2019 CommandLineArgumentParsing
ERROR(S):
Verb '-n' is not recognized.
--help Display this help screen.
--version Display version information.
0
I believe this issue is with this line..
CommandLine.Parser.Default.ParseArguments(args, typeof(SomeOptions));
It seems like this line should be this..
CommandLine.Parser.Default.ParseArguments(args, typeof(options));
However the compiler is complaining that "'options' is a variable but is used like a type"
What am I doing wrong?
I figured this out about two seconds after I asked the question..
Replace..
CommandLine.Parser.Default.ParseArguments(args, typeof(SomeOptions));
With...
Parser.Default.ParseArguments<SomeOptions>(args).WithParsed(parsed => options = parsed);

C# Windows Service - this keyword error

I have the following code which works fine when I use it within a Windows Forms application, however the application I'm writing needs to run as a Windows service, and when I moved my code into the Windows Service template in Visual Studio 2015 Community Edition, I get the following error.
Cannot implicitly convert type "MyWindowsService.Main" to "System.ComponentModel.ISynchronizeVoke". An explicit conversion exists (are you missing a cast?)
Could anyone shed some light on why I am getting this error, and what I need to do to resolve it?
The code which throws the error is the line below, and it is located within the OnStart method of my main class (named Main.cs). The code is used to create an instance of the DataSubscriber class (AdvancedHMI library).
dataSubscribers[dataSubscriberIndex].SynchronizingObject = this;
It has to have something to do with the fact that the code is in a Windows service template, because using this works perfectly in my forms application running the same code.
UPDATE
Correction, I've attempted to cast this to the required type, and now get the following error on run.
Additional information: Unable to cast object of type 'MyWindowsService.Main' to type 'System.ComponentModel.ISynchronizeInvoke'.
Code:
dataSubscribers[dataSubscriberIndex].SynchronizingObject = (System.ComponentModel.ISynchronizeInvoke)this;
UPDATE
I've included the entire contents of the Main.cs file from my Windows Service application.
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using MySql.Data.MySqlClient;
using AdvancedHMIDrivers;
using AdvancedHMIControls;
using MfgControl.AdvancedHMI.Drivers;
using MfgControl.AdvancedHMI.Controls;
using System.Collections.ObjectModel;
namespace PLCHistoricDataHarvester {
public partial class Main : ServiceBase {
private EthernetIPforCLXCom commObject = new EthernetIPforCLXCom();
private globals globals = new globals();
private Dictionary<String, String> operationLines = new Dictionary<String, String>();
private Dictionary<String, String> tags = new Dictionary<String, String>();
private Collection<DataSubscriber> dataSubscribers = new Collection<DataSubscriber>();
private int harvesterQueueCount = 0;
private string harvesterInsertValues = String.Empty;
public Main() {
InitializeComponent();
}
protected override void OnStart(string[] args) {
// Initialize our harvester program
initializeHarvester();
Console.WriteLine("The program has started");
}
protected override void OnStop() {
// Call code when the service is stopped
Console.WriteLine("Program has stopped");
Console.ReadLine();
}
public void initializeHarvester() {
// First, we connect to the database using our global connection object
globals.dbConn.DatabaseName = "operations";
if (!globals.dbConn.IsConnect()) {
// TODO: Unable to connect to database. What do we do?
}
// Second, we connect to the database and pull data from the settings table
globals.initializeSettingsMain();
// Set IP address of PLC
commObject.IPAddress = globals.getSettingsMain("Processor_IP");
// Pull distinct count of our parent tags (Machines ex: Line 1, etc)
operationLines = globals.getOperationLines();
// If we have at least 1 operation line defined...we continue
if (operationLines.Keys.Count > 0) {
//Now we loop over the operation lines, and pull back the data points
int dataSubscriberIndex = 0;
foreach (KeyValuePair<String, String> lines in operationLines) {
int line_id = int.Parse(lines.Key);
string name = lines.Value;
tags = globals.getTags(line_id);
// If we have at least 1 tag for this operation line, we continue...
if (tags.Keys.Count > 0 && tags["tags"].ToString().IndexOf(",") != -1) {
// Create our dataSubscriber object
dataSubscribers.Add(new DataSubscriber());
dataSubscribers[dataSubscriberIndex].SynchronizingObject = (ISynchronizeInvoke)this;
dataSubscribers[dataSubscriberIndex].CommComponent = commObject;
dataSubscribers[dataSubscriberIndex].PollRate = 1000;
dataSubscribers[dataSubscriberIndex].PLCAddressValue = tags["tags"];
dataSubscribers[dataSubscriberIndex].DataChanged += new EventHandler<MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs>(subscribeCallback);
// Increment our dataSubscriberIndex
dataSubscriberIndex++;
}
}
}
}
private void subscribeCallback(object sender, MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs e) {
// code removed as it is irrelevant
}
}
}
The error message says this:
An explicit conversion exists (are you missing a cast?)
So add a cast like this:
dataSubscribers[dataSubscriberIndex].SynchronizingObject = (ISynchronizeInvoke)this;
^^^^^^^^^^^^^^^^^^^^
//Add this
If you've got a console app, the easiest way to convert it to a windows service is by using Topshelf, a nuget package which lets you run in either console mode or nt service mode.
Here's the quickstart guide.
We use it to write services all the time and it helps you avoid this kind of fragile shenanigans.

Unity SQLite local database

I am making a small game in Unity and I'm in need of a database. I tried using SQLite database because that seemed to be recommended by the web.
Now I'm having troubles with actually connecting to the local database via c#.
I implemented the Data in SQLite .dll's.
I am trying to get 1 name from the database that I created using SQLite developer.
Below is my DataConnection class, which I use to connect to the database.
using UnityEngine;
using System.Collections;
using System.Data;
using Mono.Data.SqliteClient;
public class Dataconnection : MonoBehaviour {
private string _constr = #"Data Source=C:\Program Files (x86)\SharpPlus\SqliteDev\GameDatabase.db;Version=3;";
private IDbConnection _dbc;
private IDbCommand _dbcm;
private IDataReader _dbr;
public Dataconnection()
{
}
public Dataconnection(string constring)
{
_constr = constring;
}
public string ExcecuteQuery(string SQL)
{
string output = "";
try
{
_dbc = new SqliteConnection(_constr);
_dbc.Open();
_dbcm = _dbc.CreateCommand();
_dbcm.CommandText = SQL;
_dbr = _dbcm.ExecuteReader();
}
catch
{
}
while (_dbr.Read())
{
output = _dbr.GetString(0);
}
_dbc.Close();
return output;
}
}
Then I call the following method from another class:
datacon.ExcecuteQuery("SELECT name FROM employee WHERE empid = 1;");
I get the following errors when running the code:
So I'm guessing it has something to do with a 32/64 -bit mismatch or is there something wrong with creating an instance of a script like this?:
private Dataconnection datacon;
void Start()
{
datacon = new Dataconnection();
}
Happy to receive any help at all. I'm familiar with using database, just new to SQLite.
It says it cannot load the native sqlite.dll because you have there 64 bit version and it needs 32 bit
Place this in your app folder https://www.sqlite.org/2015/sqlite-dll-win32-x86-3081001.zip
Please fill that empty catch on line 38 with a throw;
as there is an exception hidden there which is the true cause of the null reference.
You could also post your connection string so I could make this answer better.
I got it working now. The problem was my that one of the SQLite .dll's was still 32bit. I did this tutorial over again and searched google for the 64bit .dll files and now it's working.

Why can't I read a db4o file created by a Java app in a C# app?

I have a db4o database that was generate by a Java app and I'm trying to read it using a C# app.
However, when running the following line of code:
IObjectContainer db = Db4oEmbedded.OpenFile(#"..\..\..\Databases\people.db4o");
I get the following error:
Unable to cast object of type
'Db4objects.Db4o.Reflect.Generic.GenericObject' to type
'Db4objects.Db4o.Ext.Db4oDatabase'.
Any ideas? I know there are person objects that contain personId fields (along with others) in the DB. I'm using db4o version 8. I'm not sure what version was used to generate the database.
The entire program is:
using System;
using System.Collections.Generic;
using System.Linq;
using Db4objects.Db4o;
using Db4objects.Db4o.Config;
using MyCompany.Domain;
namespace MyCompany.Anonymizer
{
internal class Program
{
// Private methods.
private static IEmbeddedConfiguration ConfigureAlias()
{
IEmbeddedConfiguration configuration = Db4oEmbedded.NewConfiguration();
configuration.Common.AddAlias(new TypeAlias("com.theircompany.Person", "MyCompany.Domain.Person, MyCompany.Domain"));
configuration.Common.Add(new JavaSupport());
return configuration;
}
private static void Main(string[] args)
{
IObjectContainer db = Db4oEmbedded.OpenFile(#"..\..\..\Databases\people.db4o");
try
{
IList<Person> result = db.Query<Person>();
for (int i = 0; i < result.Count; i++)
{
Person person = result[i];
Console.WriteLine(string.Format("Person ID: {0}", person.personId));
}
}
finally
{
db.Close();
}
}
}
}
The most common scenario in which this exception is thrown is when db4o fails to resolve the type of a stored object.
In your case, db4o is failing to read one of its internal objects which makes me believe you have not passed the configuration to the OpenFile() method (surely, the code you have posted is not calling ConfigureAlias() method);
Keep in mind that as of version 8.0 no further improvement will be done regarding cross platform support (you can read more details here).

After updating EnvironmentVariable - PATH - I still get a FileNotFoundException on Windows 2003 Server

I'm just starting with a new product and I guess I don't understand the PATH variable. My documentation says to update the PATH like this which I do successfully in a little console application:
using HP.HPTRIM.SDK;
namespace TestSDKforTRIM71
{
class Program
{
static void Main(string[] args)
{
string trimInstallDir = #"C:\Program Files\Hewlett-Packard\HP TRIM";
string temp = Environment.GetEnvironmentVariable("PATH") + ";" + trimInstallDir;
Environment.SetEnvironmentVariable("PATH", temp);
DoTrimStuff();
}
public static void DoTrimStuff()
{
using (Database db = new Database())
{
db.Connect();
Console.WriteLine(db.Id);
}
Console.ReadKey();
}
}
}
In the above project, I have a reference to HP.HPTRIM.SDK which exists at:
C:\Program Files\Hewlett-Packard\HP TRIM\HP.HPTRIM.SDK.dll
After the above ran successfully, I tried to permanently change the PATH by using Control Panel:System:Advanced:Environment Variables. I verified the above PATH by examining the registry at HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment. I see the following as the last entry in the PATH value:
;C:\Program Files\Hewlett-Packard\HP TRIM\
I thought this would permanently SET this at the end of the PATH but when I run the above console program with a few lines commented out I get the FileNotFoundException (see below). I am confused about how to get this in the PATH and not have to worry about it anymore.
using HP.HPTRIM.SDK;
namespace TestSDKforTRIM71
{
class Program
{
static void Main(string[] args)
{
//string trimInstallDir = #"C:\Program Files\Hewlett-Packard\HP TRIM";
//string temp = Environment.GetEnvironmentVariable("PATH") + ";" + trimInstallDir;
//Environment.SetEnvironmentVariable("PATH", temp);
DoTrimStuff(); // without setting the PATH this fails despite being in REGISTRY...
}
public static void DoTrimStuff()
{
using (Database db = new Database())
{
db.Connect();
Console.WriteLine(db.Id);
}
Console.ReadKey();
}
}
}
Only newly started processes that don't inherit their environment from their parent will have the updated PATH. You'll have to at least restart the Visual Studio hosting process, close and re-open your solution. To cover all possible corners, log out and log back in so that Windows Explorer (and thus Visual Studio) also start using the updated environment.

Categories

Resources