how do we process a cube or access OLAP database through ASP.Net with C# code? what is the component to be used, in C#.Net for connecting OLAP database or process actions in anaysis Services ?
For processing, use Microsoft.AnalysisServices library, example code looks like:
Server server = new Server();
server.Connect(cubeConnectionString);
Database database = server.Databases.FindByName(databaseName);
Cube cube = database.Cubes.FindByName(cubeName);
cube.Process(ProcessType.ProcessFull);
For querying, use Microsoft.AnalysisServices.AdomdClient library, example code looks like:
using (Adomd.AdomdConnection adomdConnection = new Microsoft.AnalysisServices.AdomdClient.AdomdConnection())
{
adomdConnection.ConnectionString = cubeConnectionString;
Adomd.AdomdCommand adomdCommand = new Microsoft.AnalysisServices.AdomdClient.AdomdCommand();
adomdCommand.Connection = adomdConnection;
adomdCommand.CommandText = mdxQuery;
adomdConnection.Open();
cellSet = adomdCommand.ExecuteCellSet();
adomdConnection.Close();
}
Note that the two namespaces overlap, so you may need to alias if you use them in the same place.
http://msdn.microsoft.com/en-US/library/ms124924(v=SQL.90).aspx
http://msdn.microsoft.com/en-us/library/ms123483(v=SQL.90).aspx
You must process the database, not the cube. Because the cube has only the measures not the dimensions inside. This can give some conflicts.
To Prozess all, Cubes and Dimensions you must process the whole database:
Server server = new Server();
server.Connect(cubeConnectionString);
Database database = server.Databases.FindByName(databaseName);
database.Process(ProcessType.ProcessFull);
Answer for this already shared above but just sharing that I too had used the same Microsoft.AnalysisServices by API referring the sample project downloaded from my blog post to process cube from C# but when the dimension data gets changed then you need to process the database rather cube.
Also you can use EffectiveUserName property of connection string when an end user identity must be impersonated on the server.
NOTE: To use EffectiveUserName property, the caller must have administrative permissions in Analysis Services.
This example was done with Visual Studio Express 2012 and $44 copy of Ms SQL 2012 (God bless Microsoft for providing so much functionality for so little money). The OS was Win 8 pro.
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//the next 2 using's had to be downloaded and "Add Reference"d for Visual Studio Express 2012
using Microsoft.AnalysisServices;
using Microsoft.AnalysisServices.AdomdClient;
using System.Windows.Forms;
using System;
using System.Data;
using System.Drawing;
namespace SSASDataview
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
private void RunSSAS(object sender, EventArgs e)
{
//i don't think Dataset is in the Analysis Services directives
DataSet ds = new DataSet();
// provider is the constant olap. datasource is the same server name you provide for Mgmt Studio or localhost
// initial catalog is tricky and important. It is not a standard ms sql database you see in Management Studio,
// even if your cube was create with tables from a particular database.
// the only place I was able to see "initial catalog" value was a File -> Open -> Analysis Services Database in 2012 Management Studio
// it was also the name of the VS2010 solution I used to create the cube.
AdomdConnection myconnect = new AdomdConnection(#"provider=olap;initial catalog=GLCubeThree;datasource=localhost");
AdomdDataAdapter mycommand = new AdomdDataAdapter();
mycommand.SelectCommand = new AdomdCommand();
mycommand.SelectCommand.Connection = myconnect;
// this query was created by the "Browser" you see for an Analysis Services project
// if you poke around the icons on the browser table the Design Mode icon will give you the cube query
// I think it's an MDX query, threre are also xml queries you can run with adomd
mycommand.SelectCommand.CommandText = "SELECT NON EMPTY { [Measures].[Per Balance] } ON COLUMNS, NON EMPTY { ([Gltime].[Fisc Per].[Fisc Per].ALLMEMBERS ) } DIMENSION PROPERTIES MEMBER_CAPTION, MEMBER_UNIQUE_NAME ON ROWS FROM ( SELECT ( { [Gltime].[Fisc Per].&[201301], [Gltime].[Fisc Per].&[201302], [Gltime].[Fisc Per].&[201307] } ) ON COLUMNS FROM [GL Cube]) CELL PROPERTIES VALUE, BACK_COLOR, FORE_COLOR, FORMATTED_VALUE, FORMAT_STRING, FONT_NAME, FONT_SIZE, FONT_FLAGS";
myconnect.Open();
mycommand.Fill(ds, "tbl");
myconnect.Close();
// the below assigns the results of the cube query to a dataGridView
// if you drag a dataGridView control to your pallete it will create exactly
// what you need for the line below to work.
// your project type has to be a Window Forms Applications
// this code shown here is in the default Form1.Designer.cs not Form1.cs
dataGridView1.DataSource = new DataView(ds.Tables[0]);
}
private void Quit_Click(object sender, EventArgs e)
{
this.Close();
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
#endregion
private System.Windows.Forms.DataGridView dataGridView1;
private System.Windows.Forms.Button runssas;
private System.Windows.Forms.Button quit;
}
}
Related
I'm following this example, ClientMongo to connect a WPF application to my MongoDB database via the connection string. But I get an error on the MongoClient when I call the GetServer method. The error states that GetServer doesn't exist, although the correct using references and usings have been added.
Can anyone spot if I've missed a step in setting this up? Or is there an alternative solution to create a connection with the remote DB?
This is the code I've used to connect, similar to the example above. The user and password have been starred out for privacy:
using MongoDB.Bson;
using MongoDB.Driver;
namespace MongoDBApp
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private string connectionString = "mongodb://<brian****>:<********123;>#ds048878.mongolab.com:48878/orders";
public MainWindow()
{
InitializeComponent();
var mongoUrl = MongoUrl.Create(connectionString);
var server = new MongoClient(connectionString).GetServer();
return server.GetDatabase(mongoUrl.DatabaseName);
}
}
}
If you are using the 2.x Version of the C# driver, forget about the Server object.
You can get your Database directly from the client:
var client = new MongoClient("<connectionString>");
return this.Client.GetDatabase("<databaseName>");
I want to track the files which are opened by the user, and select them by one particular extension. If the opened file has that extension, then I want to assign it's file path to a variable for further processing. Example applications are very cpu demanding. Is there an easy, efficient way to do that?
System wide monitoring of file-->open events (including network drives, thumb drives, etc) would require you to write a FS filter driver.
Since you have access to the machine, and you definitely need system wide access, you could simply write a simple app that will be associated with the Powerpoint extensions, perform the copy, then open Powerpoint using the filepath as a command line argument. It would look similar to the following:
using System;
using System.Windows;
using System.Diagnostics;
using System.IO;
namespace WpfApplication1
{
internal class MainWindow : Window
{
public MainWindow()
{ }
[STAThread()]
static void Main(string[] args)
{
if (args.Length == 0)
{
// [ show error or print usage ]
return;
}
if (!File.Exists(args[0]))
{
// [ show error or print usage ]
return;
}
// Perform the copy
FileInfo target = new FileInfo(args[0]);
string destinationFilename = string.Format("X:\\ExistingFolder\\{0}", target.Name);
File.Copy(target.FullName, destinationFilename);
// You may need to place the filename in quotes if it contains spaces
string targetPath = string.Format("\"{0}\"", target.FullName);
string powerpointPath = "[FullPathToPowerpointExecutable]";
Process powerpointInstance = Process.Start(powerpointPath, targetPath);
// This solution is using a wpf windows app to avoid
// the flash of the console window. However if you did
// wish to display an accumulated list then you may choose
// to uncomment the following block to display your UI.
/*
Application app = new Application();
app.MainWindow = new MainWindow();
app.MainWindow.ShowDialog();
app.Shutdown(0);
*/
Environment.Exit(0);
}
}
}
Hope this helps.
I have a requirement where I need to dump my Excel data in SQL Server table. The excel files could be varying (different no. of columns each time) and for each excel source file a new table has to be created everytime in SQL Server.
I tried with SSIS tasks coming across things that Mapping between input/output columns has to be predefined in package. Also, the destination table I am dumping data in has to be present before executing "OLE DB Destination" task.
To overcome some limitations, I did few workarounds:
Created a sample table in my database with 50 columns (because that is the max. columns I can have at any point of time in my source excel).
Before package executes I take a copy of that sample table giving it a name as I need to have different tables for each source.
Passing Excel source file dynamically to package through c# code and SSIS Variables.
Since my initial mapping is between 50 input/output columns in package, when the next excel reaches package with less no. of columns, package execution fails.
I am running the package through c# code, also when i independently run this package in BIDS passing SSIS variable value there itself, it fails with invalid column references error.
I have to run this package through code and I can't everytime remap it on failure.
I can't paste a snapshot of Package as of my reputation on this forum. Its a simple package with 2 tasks i.e. 'Excel Source' & 'OLE DB Destination'. The only issue I am facing is with dynamic mapping in package. Rest all is working fine.
Please help me out with this. Thanks in Advance!!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SqlServer.Dts.Runtime;
namespace SSRSReports
{
public partial class About : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
btnpkg.Visible = true;
}
protected void btnpkg_Click(object sender, EventArgs e)
{
string newtableName = "DATA_MD0000001_I606423";
string sourceExcel = FileUpload1.PostedFile.FileName;
DataQuery(newtableName);
RunPackage(sourceExcel, newtableName);
}
public void DataQuery(string newtableName)
{
DataClasses1DataContext dc = new DataClasses1DataContext();
dc.ExecuteCommand("select * into" + " " + newtableName + " " + "from DummyTable");
}
public void RunPackage(string SourceExcelPath, string DestinationTableName)
{
string pkgLocation;
Package pkg;
Application app;
DTSExecResult pkgResults;
Variables vars;
lblResults.Visible = false;
pkgLocation =
#"C:\Visual Studio 2008\Projects\DemoProject\DemoProject\Package.dtsx";
app = new Application();
pkg = app.LoadPackage(pkgLocation, null);
vars = pkg.Variables;
vars["SourceExcelFile"].Value = SourceExcelPath;
vars["DestinationTableName"].Value = DestinationTableName;
pkgResults = pkg.Execute(null, vars, null, null, null);
if (pkgResults == DTSExecResult.Success)
lblResults.Text = "Package ran successfully";
else
lblResults.Text = "Package failed";
lblResults.Visible = true;
}
}
}
Im trying to get my notefunction to post the current city you are in by using your gps coordinates when saving a note. Right now it's only showing "unknown location". Im kinda lost right now and i have worked so long with this code to try and get it to work so please could anyone tell me what i have done wrong?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Device.Location;
using System.Text;
using System.IO.IsolatedStorage;
using System.IO;
using Secret.myTerraService;
namespace Secret
{
public partial class AddNotePage : PhoneApplicationPage
{
private IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
private string location = "";
#region Hämtar din geografiska position
public AddNotePage()
{
InitializeComponent();
GeoCoordinateWatcher watcher;
watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Default)
{
MovementThreshold = 20
};
watcher.PositionChanged += this.watcher_PositionChanged;
watcher.StatusChanged += this.watcher_StatusChanged;
watcher.Start();
}
private void watcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
{
switch (e.Status)
{
case GeoPositionStatus.Disabled:
// location is unsupported on this device
break;
case GeoPositionStatus.NoData:
// data unavailable
break;
}
}
private void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
var epl = e.Position.Location;
// Access the position information thusly:
epl.Latitude.ToString("0.000");
epl.Longitude.ToString("0.000");
epl.Altitude.ToString();
epl.HorizontalAccuracy.ToString();
epl.VerticalAccuracy.ToString();
epl.Course.ToString();
epl.Speed.ToString();
e.Position.Timestamp.LocalDateTime.ToString();
}
void client_ConvertLonLatPtToNearestPlaceCompleted(object sender, myTerraService.ConvertLonLatPtToNearestPlaceCompletedEventArgs e)
{
location = e.Result;
//throw new NotImplementedException();
}
#endregion
#region Knappfunktioner
private void AppBar_Cancel_Click(object sender, EventArgs e)
{
navigateBack();
}
private void AppBar_Save_Click(object sender, EventArgs e)
{ // spara en ny anteckning
if (location.Trim().Length == 0)
{
location = "Okänd Plats";
}
// skapa namnet på filen
StringBuilder sb = new StringBuilder();
sb.Append(DateTime.Now.Year);
sb.Append("_");
sb.Append(String.Format("{0:00}", DateTime.Now.Month));
sb.Append("_");
sb.Append(String.Format("{0:00}", DateTime.Now.Day));
sb.Append("_");
sb.Append(String.Format("{0:00}", DateTime.Now.Hour));
sb.Append("_");
sb.Append(String.Format("{0:00}", DateTime.Now.Minute));
sb.Append("_");
sb.Append(String.Format("{0:00}", DateTime.Now.Second));
sb.Append("_");
location = location.Replace(" ", "-");
location = location.Replace(", ", "_");
sb.Append(location);
sb.Append(".txt");
//spara filen i Isolated Storage
var appStorage = IsolatedStorageFile.GetUserStoreForApplication();
try
{
using (var fileStream = appStorage.OpenFile(sb.ToString(), System.IO.FileMode.Create))
{
using (StreamWriter sw = new StreamWriter(fileStream))
{
sw.WriteLine(editTextBox.Text);
}
}
}
catch
{
// åtgärda vid senare tillfälle..
}
//Klart Navigera tillbaka till NoteMainPage
navigateBack();
}
When testing this, I can see a few points where your code could break. You should debug with breakpoints to actually confirm that your app is getting GPS location data. If not, use the Windows Phone emulator and run a GPS simulation (and then confirm again).
Next, once you know that your GPS data is coming in and formatted correctly for your Terra Web Service, confirm that the data is actually being sent to the Terra Web Service and that data is being returned from the web service call. If your Terra Web Service is returning "Unknown Location" still, try again but this time plot the GPS location near a major city to increase the odds of the web service knowing what city you are close to. If you are still returning "Unknown Location" then you can be fairly certain that the issue resides with the web service provider.
In my experience with the Windows Phone location services (I've only used dev phones with WiFi access (i.e. no sim)), location data sometimes takes a few seconds or minutes to pickup. If you're testing this on a physical dev phone in a basement or an area with limited access for the GPS to find you, odds are the data isn't being generated. Also, because the Windows Phone location data isn't necessarily instant, you can't always call it on the fly and expect it to have location data ready. In my experience I have had the user opt in to location services (per the Windows Phone Marketplace submission requirements) and then have a background agent pull location data while the user is using the app. That way location data is likely to be ready by the time user would need it (like your example when the user saves the note).
Here's a working example I made for you in C# that will work for your Windows Phone app. The sample is a console app for the sake of simplicity and time. If you can't figure it out still, I'll code it up for Windows Phone. With this though you really have everything you need to make it work, just plug in the lat and long variables. Download Working Source Code (Visual Studio 2010)
C# Source code snippet
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TerraServiceExample.com.msrmaps; // add the service using statement
// http://msrmaps.com/terraservice2.asmx
namespace TerraServiceExample
{
class Program
{
/// <summary> The main entry point for the application. </summary>
static void Main(string[] args)
{
// Create the GPS point from your location services data
LonLatPt location = new LonLatPt();
// Modify Lat and Lon based on your needs
// This example uses the GPS Coordinates for "Eau Claire, Wisconsin, United States"
location.Lat = 44.811349;
location.Lon = -91.498494;
// Create a new TerraService object
TerraService ts = new TerraService();
// Output the nearest location from the TerraService
Console.WriteLine(ts.ConvertLonLatPtToNearestPlace(location));
// For console app to stay open/close easily
Console.WriteLine("Press any key to close window...");
Console.ReadKey();
// Lastly, appreciate the Microsoft folks that made this available for free
// They are all interesting individuals but you should read about Jim Gray via Wikipedia to
// understand some history behind this cool web service.
}
}
}
I am using the following code under ASP.NET 4.0 framework to obtain the version of MSI file from a web app:
string strVersion = "";
try
{
Type InstallerType;
WindowsInstaller.Installer installer;
InstallerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
installer = (WindowsInstaller.Installer)Activator.CreateInstance(InstallerType);
WindowsInstaller.Database db = installer.OpenDatabase(strMSIFilePath, 0);
WindowsInstaller.View dv = db.OpenView("SELECT `Value` FROM `Property` WHERE `Property`='ProductVersion'");
WindowsInstaller.Record record = null;
dv.Execute(record);
record = dv.Fetch();
strVersion = record.get_StringData(1).ToString();
dv.Close();
//db.Commit();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(dv);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(db);
}
catch
{
//Failed
strVersion = "";
}
It works fine except that when the code finishes running it holds an internal MSI file handle so when I try to move or rename the MSI file I get the error that the file is still in use. This continues until I actually navigate away from the ASPX page that calls the method above.
My question is, I obviously didn't close some handle or object in the code above. But what could that be?
PS. I'm testing it in a development IDE from VS2010.
EDIT: Edited the code like it should be after Adriano's suggestion. Thanks!
The COM object has not been released (it should be auto-released when it goes out of scope but in .NET this doesn't work really well). Because it does not implement the IDisposable interface you can't call its Dispose() method and you can't use it inside an using statement. You have to explicitly call Marshal.FinalReleaseComObject. For example:
try
{
// Your stuffs
}
finally
{
dv.Close();
Marshal.FinalReleaseComObject(dv);
Marshal.FinalReleaseComObject(db);
}
Moreover note that you do not really need a call to the Commit() method because you didn't make any change but just a query.
FWIW, you should be using Windows Installer XML (WiX) Deployment Tools Foundation (DTF). It's an FOSS project from Microsoft that can be found on CodePlex. It has MSI interop libraries with classes that are very similar to the COM classes but implement IDisosable and use P/Invoke instead of COM behind the scenes. There is even support for Linq to MSI if you want. And the full source code is available.
DTF is the gold standard for MSI interop in a .NET world. Here are two examples:
using System;
using System.Linq;
using Microsoft.Deployment.WindowsInstaller;
using Microsoft.Deployment.WindowsInstaller.Linq;
namespace ConsoleApplication3
{
class Program
{
const string DATABASE_PATH = #"C:\FOO..MSI";
const string SQL_SELECT_PRODUCTVERSION = "SELECT `Value` FROM `Property` WHERE `Property`='ProductVersion'";
static void Main(string[] args)
{
using (Database database = new Database(DATABASE_PATH, DatabaseOpenMode.ReadOnly))
{
Console.WriteLine(database.ExecuteScalar(SQL_SELECT_PRODUCTVERSION).ToString());
}
using (QDatabase database = new QDatabase(DATABASE_PATH, DatabaseOpenMode.ReadOnly))
{
var results = from property in database.Properties where property.Property == "ProductVersion" select property.Value;
Console.WriteLine(results.AsEnumerable<string>().First());
}
}
}
}
try to Dispose the Objects.
dv.Dispose();
db.Dispose();