Problem with different datatypes - c#

I have a project that runs some code on SSIS in SqlServer 2005 and SqlServer 2008. My problem is that i maintain two Visual Studio solutions for this, because the data types for the two versions of the SQL Server are different (ends with ..90 on SQL Server 2005 and ...10 on SQL Server 2008). They are in different assemblies also.
Is there an easy way to manage this, both in development and in build, i hate having to enter my code in two places (each solution) and with SQL Server 2011 coming i suspect that i will have to do it three times. How do you solve this, or any advice on how to solve this in general?
Edit:
Here is a sample of what I'm doing, as i see it its hard to factor this out in an interface, or?
foreach (IDTSVirtualInputColumn90 virtualColumn in virtualInput.VirtualInputColumnCollection)
{
if (string.Compare(virtualColumn.Name, columnTransformation.FromColumn.Name, true) == 0 || (columnTransformation.FromColumn.Preformatted && columnTransformation.FromColumn.Name.EndsWith(" as \"" + virtualColumn.Name + "\"")))
{
convInstance.SetUsageType(input.ID, virtualInput, virtualColumn.LineageID, DTSUsageType.UT_READONLY);
IDTSOutputColumn90 outputColumn = convComponent.OutputCollection[0].OutputColumnCollection.New();
outputColumn.Name = virtualColumn.Name + " (Converted)";
outputColumn.SetDataTypeProperties(columnTransformation.ToColumn.DataType, columnTransformation.ToColumn.Length, columnTransformation.ToColumn.Precision, columnTransformation.ToColumn.Scale, 0);
outputColumn.ErrorRowDisposition = DTSRowDisposition.RD_FailComponent;
outputColumn.TruncationRowDisposition = DTSRowDisposition.RD_IgnoreFailure;
IDTSCustomProperty90 outputProp = outputColumn.CustomPropertyCollection.New();
outputProp.Name = "SourceInputColumnLineageID";
outputProp.Value = virtualColumn.LineageID;
outputProp = outputColumn.CustomPropertyCollection.New();
outputProp.Name = "FastParse";
outputProp.Value = false;
break;
}
}

It's not really clear what your code is doing, but the normal approach to this sort of thing would be to create an interface or abstract class, and then have multiple implementations (or derived classes) for the specialized behaviour. All the common code can just talk to the abstraction, letting the implementation deal with the details.

Related

Saving Modules correctly using Access-Interop

Even though my last questions weren't accepted well, I will give it another try.
I'm working on a program that is capable of controlling a lot of office-application behaviour by using the COM/Interop-Interface Microsoft provided for Word/Access/Excel. Still some functions differ from each other in the way that they are kept specific for the program that gets addressed.
My ambition is to Insert Macro-Code to an existing Access-Database and run the code while the Database is open and delete the code before the Database closes down. Partially this works as wished by using following C# code:
VBProject found = null;
Access.Application currApplication = this._currentInstance.Application;
if (target.Equals("") || scriptText.Equals(""))
return false;
foreach (VBProject vb in currApplication.VBE.VBProjects)
{
if (currApplication.CurrentDb().Name.Equals(vb.FileName))
{
found = vb;
break;
}
}
if (found != null)
{
foreach (VBComponent foundComponent in found.VBComponents)
{
if (foundComponent.Name.Equals(target))
{
return true;
}
}
VBComponent module = found.VBComponents.Add(vbext_ComponentType.vbext_ct_StdModule);
module.Name = target;
module.CodeModule.AddFromString(scriptText);
return true;
}
else
{
return false;
}
Now in particular, Access makes a diversion between VBA-Code-Modules which are visible in the Code-Editor and Modules which are loaded into the Database itself. For inserting the Module into the Database, it needs to be saved another time. When using the GUI, there's a window that popsup and asks for the Name to be used when saving it into the DB. It already takes the correct one etc. and it's fine after doing it by hand.
Besides the manual solution I found no way to do this step programatically.
Initial thoughts were:
currApplication.DoCmd.OpenModule(target, Type.Missing);
currApplication.DoCmd.Save(Access.AcObjectType.acMacro, target);
or
found.VBE.ActiveVBProject.SaveAs("");
The only two methods I could imagine would be doing the step I wanted. VBE in it's new .NET compatible form is documented very bad. Methods that would have applied to the native version are not guilty anymore. So I'm stuck with it now.
In case someone asks, why would you save the module at all, because once it's inserted in VBE it can be run like any other module listed in Access also, that's true, but for some unknown reasons this seems to be more fault-prone then to save it twice. Got runtime errors (like 2501) while launching the macro, which is not the case when it's saved properly.
Keeping it forever in the Access-Databases would be the last option but since those are many MDBs and thus they are changing frequently, I thought it would be nice to have it dynamic.
Hope somebody understands what I wrote here, (not so easy for me), and is enabled to help somehow :)
Thanks for all the reading. Looking forward for some good results, from the best community, hehe.

Telerik OpenAccess ORM with SQL Server 2005

I'm trying out this ORM & new to this. I have following code:
IObjectScope scope = Database.Get("MyConnection").GetObjectScope();
try
{
scope.Transaction.Begin();
Reading r = new Reading();
r.ReadingURL = reading.ReadingURL;
r.IsActive = true;
scope.Add(r);
scope.Transaction.Commit();
}
finally
{
scope.Dispose();
}
When I run this I get following error on "Add":
Telerik.OpenAccess.Exceptions.InvalidOperationException: Class
'WritingChallenge.Reading' is persistent but not known in this
context.
It seems for some reason database connection is lost? I'm not sure what is the issue here.
The issue here is that the model that was connected to the WritingReplacementConnection was having no information about the WritingChallenge.Reading type.
Did you specify a mappingConfiguration that included this type?
You can also ask this kind of questions in the forums at Telerik Forums - .NET ORM.

How can i figure out a max_user_connections on ASP.NET | MySql application?

last year i developed an ASP.NET Application implenting MVP Model.
The site is not very large (about 9.000 views/day).
It is a common application witch just desplays articles, supports scheduling (via datetime),vote and views, sections and categories.
From then i create more than 15 sites with the same motive ( The database michanism was build in the same logic).
What i did was :
Every time a request arrive i have to take articles, sections, categories, views and votes from my Database and display them to the user...like all other web apps.
My database objects are somthing like the above :
public class MyObjectDatabaseManager{
public static string Table = DBTables.ArticlesTable;
public static string ConnectionString = ApplicationManager.ConnectionString;
public bool insertMyObject(MyObject myObject){/*.....*/}
public bool updateMyObject(MyObject myObject){/*.....*/}
public bool deleteMyObject(MyObject myObject){/*.....*/}
public MyObject getMyObject(int MyObjectID){/**/}
public List<MyObject> getMyObjects( int limit, int page, bool OrderBy, bool ASC){/*...*/}
}
When ever i want to communicate to the database i do something like the above
MySqlConnection myConnection = new MySqlConnection(ConnectionString);
try
{
myConnection.Open();
MySqlCommand cmd = new MySqlCommand(myQuery,myConnection);
cmd.Parameters.AddWithValue(...);
cmd.ExecuteReader(); /* OR */ ExecuteNonQuery();
}catch(Exception){}
finally
{
if (myConnection != null)
{
myConnection.Close();
myConnection.Dispose();
}
}
Two months later i've run into trouble.
The performance start falling down and the database starts to return errors : max_user_connections
Then i think.. " Let's cache the page "
And the start to use Output cache for the pages.
(not a very sophisticated good idea..)
12 months later my friend told to me to create a "live" article...
an article that can be updated without any delay. (from the output cache...)
Then it came into my mind that : " Why to use cache? joomla etc **doesn't"
So...i remove the magic "Output cache" directive...
From then i run again into the same problem...
MAX_USER_CONNETCTIONS! :/
What i'm doing wrong?
I know that my code communicates alot with the database but...
the connection pooling?
Sorry for my english
Please...help :/
i have no idea how to figure it out:/
Thank you.
I'm running into share hosting packet
*My db is over 60mb in size*
I have more than 6000 rows in some tables like articles
*My hosting provider gives me 25 connections to the database (very large number in my opinion)*
Your code looks fine to me, although from a style perspective I prefer "using" to "try / finally / Dispose()".
One thing to check is to make sure that the connection strings you're using are identical, everywhere in your code. Most DB drivers to connection pooling based on comparing the connection strings.
You may need to increase the max_connections variable in your mysql config.
See:
http://dev.mysql.com/doc/refman/5.5/en/too-many-connections.html
Actually, Max #/connections is an OS-level configuration.
For example, under NT/XP, it was configurable in the registry, under HKLM, ..., TcpIp, Parameters, TcpNumConnections:
http://smallvoid.com/article/winnt-tcpip-max-limit.html
More important, you want to maximum the number of "ephemeral ports" needed to open new connections:
http://www.ncftp.com/ncftpd/doc/misc/ephemeral_ports.html
Windows:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
On the Edit menu, click Add Value, and then add the following registry value:
Value Name: MaxUserPort Data Type: REG_DWORD Value: 65534
Linux:
sudo sysctl -w net.ipv4.ip_local_port_range="1024 64000"

Linq 'Index was outside the bounds of the array' problem

In trying to setup a unit test for inserting an item into an SQL Server Express (2008) database using C# Linq I've encountered an error that is causing me some trouble. The Linq code is built using Visual Studio 2008.
The exception is thrown on a system running Windows XP SP2. The Linq works fine and the record is inserted appropriately on a system running Windows 7 Home Premium (64-bit).
I've dropped and re-created the database on the XP system. I've dropped and re-created the DAL and corresponding DBML on the XP system.
Other tables with unit tests for inserts to the same database work just fine.
Inserting a record into the table using a simple insert statement in SQL Server Management Studio works appropriately.
What should I look at to find the source of the problem? What should be done to resolve the problem?
Any insight as to what the error message is really trying to say would be greatly appreciated.
Error Message
System.IndexOutOfRangeException : Index was outside the bounds of the array.
Stack Trace
at
System.Data.Linq.IdentityManager.StandardIdentityManager.MultiKeyManager`3.TryCreateKeyFromValues(Object[] values, MultiKey`2& k)
at System.Data.Linq.IdentityManager.StandardIdentityManager.IdentityCache`2.Find(Object[] keyValues)
at System.Data.Linq.IdentityManager.StandardIdentityManager.Find(MetaType type, Object[] keyValues)
at System.Data.Linq.CommonDataServices.GetCachedObject(MetaType type, Object[] keyValues)
at System.Data.Linq.ChangeProcessor.GetOtherItem(MetaAssociation assoc, Object instance)
at System.Data.Linq.ChangeProcessor.BuildEdgeMaps()
at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges()
at nUnit.DAL.FacilityTests.AddFacility2() in C:\SVN\SVNRevenue360\Branches\Dev\Code\ProviderAdvantage\nUnit.CoreTests\Tests\DAL\FacilityTests.cs:line 50
Insert Code
[Test]
public void AddFacility2() {
string facilityname = "Test Facility";
try {
using (PA.Database.Revenue360DB db = new PA.Database.Revenue360DB(PA.DAL.DataAccess.ConnectionString)) {
db.Log = Console.Out;
PA.Database.Facility facility = new PA.Database.Facility();
facility.id = Guid.NewGuid();
facility.Name = facilityname;
facility.Street1 = "";
facility.Street2 = "";
facility.Street3 = "";
facility.City = "";
facility.State = "";
facility.Zip = "";
facility.Description = "";
db.Facilities.InsertOnSubmit(facility);
db.SubmitChanges(); // line 50
}
} catch (Exception ex) {
Console.WriteLine(ex.GetType().FullName + ": " + ex.Message);
Console.WriteLine(ex.InnerException == null ?
"No inner exception" :
ex.InnerException.GetType().FullName + ": " + ex.InnerException.Message);
throw;
}
}
I've looked at the following SO questions without insight as to what is causing this particular issue.
https://stackoverflow.com/questions/1087172/why-am-i-getting-index-was-outside-the-bounds-of-the-array
IndexOutOfRangeException on Queryable.Single
Strange LINQ Exception (Index out of bounds)
Take a look at this link.
Here are a few excerpts:
A common cause of this error is
associations pointing in the wrong
direction. (Something that is
extremely easy to do if editing the
model by hand, partly because the
association arrow pointer is in the
opposite end of where it would appear
in an ER diagram)
and
I was having the same problem and it
was due to the fact my primary key was
two columns instead of the traditional
one. (both guids). When I added a
third column that was the sole primary
key column, it worked.
UPDATE: Did some more poking around and found this SO post. Looks like it might have something to do with your DBML...
If the code is working on one machine and not working on another the problem should be somewhere outside. Please check if the .NET Framework version on Windows XP is the same as on Windows 7. Secondly, if its XP SP2 then the Operating System might be the cause because Microsoft has changed a lot in SP3. Also check if the database has same tables. Try to reproduce the problem on the same db, i.e. take backup from Win7 and restore it on the XP (of cause backup your data first). What else? Security permissions and connection string might have an impact too.

Use C# to interact with Windows Update

Is there any API for writing a C# program that could interface with Windows update, and use it to selectively install certain updates?
I'm thinking somewhere along the lines of storing a list in a central repository of approved updates. Then the client side applications (which would have to be installed once) would interface with Windows Update to determine what updates are available, then install the ones that are on the approved list. That way the updates are still applied automatically from a client-side perspective, but I can select which updates are being applied.
This is not my role in the company by the way, I was really just wondering if there is an API for windows update and how to use it.
Add a Reference to WUApiLib to your C# project.
using WUApiLib;
protected override void OnLoad(EventArgs e){
base.OnLoad(e);
UpdateSession uSession = new UpdateSession();
IUpdateSearcher uSearcher = uSession.CreateUpdateSearcher();
uSearcher.Online = false;
try {
ISearchResult sResult = uSearcher.Search("IsInstalled=1 And IsHidden=0");
textBox1.Text = "Found " + sResult.Updates.Count + " updates" + Environment.NewLine;
foreach (IUpdate update in sResult.Updates) {
textBox1.AppendText(update.Title + Environment.NewLine);
}
}
catch (Exception ex) {
Console.WriteLine("Something went wrong: " + ex.Message);
}
}
Given you have a form with a TextBox this will give you a list of the currently installed updates. See http://msdn.microsoft.com/en-us/library/aa387102(VS.85).aspx for more documentation.
This will, however, not allow you to find KB hotfixes which are not distributed via Windows Update.
The easiest way to do what you want is using WSUS. It's free and basically lets you setup your own local windows update server where you decide which updates are "approved" for your computers. Neither the WSUS server nor the clients need to be in a domain, though it makes it easier to configure the clients if they are. If you have different sets of machines that need different sets of updates approved, that's also supported.
Not only does this accomplish your stated goal, it saves your overall network bandwidth as well by only downloading the updates once from the WSUS server.
If in your context you're allowed to use Windows Server Update Service (WSUS), it will give you access to the Microsoft.UpdateServices.Administration Namespace.
From there, you should be able to do some nice things :)
P-L right. I tried first the Christoph Grimmer-Die method, and in some case, it was not working. I guess it was due to different version of .net or OS architecture (32 or 64 bits).
Then, to be sure that my program get always the Windows Update waiting list of each of my computer domain, I did the following :
Install a serveur with WSUS (may save some internet bandwith) : http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=5216
Add all your workstations & servers to your WSUS server
Get SimpleImpersonation Lib to run this program with different admin right (optional)
Install only the administration console component on your dev workstation and run the following program :
It will print in the console all Windows updates with UpdateInstallationStates.Downloaded
using System;
using Microsoft.UpdateServices.Administration;
using SimpleImpersonation;
namespace MAJSRS_CalendarChecker
{
class WSUS
{
public WSUS()
{
// I use impersonation to use other logon than mine. Remove the following "using" if not needed
using (Impersonation.LogonUser("mydomain.local", "admin_account_wsus", "Password", LogonType.Batch))
{
ComputerTargetScope scope = new ComputerTargetScope();
IUpdateServer server = AdminProxy.GetUpdateServer("wsus_server.mydomain.local", false, 80);
ComputerTargetCollection targets = server.GetComputerTargets(scope);
// Search
targets = server.SearchComputerTargets("any_server_name_or_ip");
// To get only on server FindTarget method
IComputerTarget target = FindTarget(targets, "any_server_name_or_ip");
Console.WriteLine(target.FullDomainName);
IUpdateSummary summary = target.GetUpdateInstallationSummary();
UpdateScope _updateScope = new UpdateScope();
// See in UpdateInstallationStates all other properties criteria
_updateScope.IncludedInstallationStates = UpdateInstallationStates.Downloaded;
UpdateInstallationInfoCollection updatesInfo = target.GetUpdateInstallationInfoPerUpdate(_updateScope);
int updateCount = updatesInfo.Count;
foreach (IUpdateInstallationInfo updateInfo in updatesInfo)
{
Console.WriteLine(updateInfo.GetUpdate().Title);
}
}
}
public IComputerTarget FindTarget(ComputerTargetCollection coll, string computername)
{
foreach (IComputerTarget target in coll)
{
if (target.FullDomainName.Contains(computername.ToLower()))
return target;
}
return null;
}
}
}

Categories

Resources