Error when adding Analysis Services Data Source View from c# code - c#

I want to create an Analysis Services database, datasource and datasource view from c# code. Everything seems to be working fine until I add a mining structure and models and try to process the structure, then i get the following error:
Errors in the high-level relational engine. The data source view does
not contain a definition for the 'dbo_Challenger201501TrainingAll'
table or view. The Source property may not have been set.
The DSV is meant to contain the same info as a table in the Data Source.
This is the code with which i create the data set and DSV:
private static object FillDataSet(SqlConnection objConnection, DataSet objDataSet, string strTableName)
{
try
{
string strCommand = "Select * from " + strTableName;
SqlDataAdapter objEmpData = new SqlDataAdapter(strCommand, objConnection);
objEmpData.MissingSchemaAction = MissingSchemaAction.AddWithKey;
objEmpData.FillSchema(objDataSet, SchemaType.Source, strTableName);
Console.WriteLine(objEmpData.ToString());
return objDataSet;
}
catch (Exception ex)
{
Console.WriteLine("Error in Creating a DataSourceView - FillDataSet. Error Message -> " + ex.Message);
return null;
}
}
private static object CreateDataSourceView(Microsoft.AnalysisServices.Database objDatabase, RelationalDataSource objDataSource, DataSet objDataSet,
string strCubeDataSourceViewName)
{
try
{
Console.WriteLine("Creating DataSourceView ...");
DataSourceView objDataSourceView = new DataSourceView();
//Add Data Source View to the Database.
objDataSourceView = objDatabase.DataSourceViews.Add(strCubeDataSourceViewName);
objDataSourceView.DataSourceID = objDataSource.ID;
objDataSourceView.Schema = objDataSet;
objDataSourceView.Update();
return objDataSourceView;
}
catch (Exception ex)
{
Console.WriteLine("Error in Creating a DataSourceView - CreateDataSourceView. Error Message -> " + ex.Message);
return null;
}
}
The code compiles and runs fine. can anyone see any reason why the DSV may not be created properly?

Related

c# How to create a Method on a Method, or Method Chain

I have created a simplified SQL Data class, and a class method for returning a ready to use resultset:
public SQL_Data(string database) {
string ConnectionString = GetConnectionString(database);
cn = new SqlConnection(ConnectionString);
try {
cn.Open();
} catch (Exception e) {
Log.Write(e);
throw;
}
}
public SqlDataReader DBReader(string query) {
try {
using (SqlCommand cmd = new SqlCommand(query, this.cn)) {
return cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
} catch {
Log.Write("SQL Error with either Connection String:\n" + cn + " \nor Query:\n" + query);
throw;
}
}
(I catch any errors, log them, and then catch the error higher up the chain. Also, I did not include the ConnectionString() code for brevity. It just returns the requested connection string. That's all.)
This all works just fine, and with a single line of code, I'm ready to .Read() rows.
SqlDataReader rs = new SQL_Data("MyDatabase").DBReader(#"SELECT * FROM Employees");
while (rs.Read()) {
// code
}
rs.Close();
I want to expand this and add a .ColumnReader() method that I want to chain to .DBReader() like this:
string empID = new SQL_Data("MyDatabase").DBReader(#"SELECT * FROM Employees).ColumnReader("EmpID");
I attempted this by adding a .ColumnReader() method, but it ends up being a method of SQL_Data() class directly, not a member or extension of .DBReader(). I also tried adding the .ColumnReader() inside the .DBReader() (like a "closure"), but that didn't work either.
Can this be done?
This ended up working for me:
public static class SQLExtentions {
public static dynamic ColumnReader(this SqlDataReader rs, string colName) {
return rs[colName];
}
}
I will have to expand on it a bit to add some error checking, and perhaps return more than just the dynamic value - like return an object with the value and it's SQL data type. But Paul and Bagus' comments got me on the right track.

COMAdminCatalogCollection.Populate throws error C#

I am using the COMAdminCatalog API for .net. I am currently getting certain properties of COM+ applications and components from an array of servers remotely. For the most part, my process doesn't have a problem retrieving this data. However, a few of the COM+ application's components will not populate and throws the following exception:
Error Message: Errors occurred accessing one or more objects - the ErrorInfo collection may have more detail (Exception from HRESULT: 0x80110401)
I try getting the ErrorInfo collection, but no errorInfo objects are returned, so that doesn't help me in trouble shooting.
Here is the documentation:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms686530(v=vs.85).aspx
Here is the method I am using to try to populate a component collection. Any help would be greatly appreciated. Thanks in advance
private static bool TryPopulateComponent(COMAdminCatalogCollection cOMAdminCatalogComponentCollection,
COMAdminCatalogObject application = null, COMAdminCatalogObject component = null, string serverName = null)
{
try
{
cOMAdminCatalogComponentCollection.Populate();
return true;
}
catch (Exception ex)
{
COMAdminCatalogCollection errorInfos = cOMAdminCatalogComponentCollection.GetCollection("ErrorInfo", varObjectKey: application.Key);
errorInfos.Populate();
foreach (COMAdminCatalogObject errorInfo in errorInfos)
{
var errorCode = errorInfo.Value["ErrorCode"];
var majorRef = errorInfo.Value["MajorRef"];
var minorRef = errorInfo.Value["MinorRef"];
var name = errorInfo.Value["Name"];
}
COMException comException = new COMException(ex.Message, ex.InnerException,
application, component, serverName);
Console.WriteLine($"Could not populate {component?.Name}");
Console.WriteLine(ex.Message);
LogTools.LogError(comException);
return false;
}
}

GET tables method is not supported for this dataset - not implemented

I am trying to use the API to query the set of tables associated with a given dataset.
This works correctly on the sample dataset and on the dataset I 'created' through the API.
But, it does not work with one of my existing datasets that was tied to an SQL datasource.
I would not think that should matter, because the data is already set up within PowerBI.
It may be that it has some rows in it that it does not understand, but the error message is not very informative:
StatusCode: 501, ReasonPhrase: 'Not Implemented'
public static void PowerBiMain()
{
token = AccessToken();
var datasetId = GetDatasets().value.GetDataset(datasetName).Id;
var tables = GetTables(datasetId);
}
public static Tables GetTables(string datasetId)
{
Tables response = null;
try
{
var request = DatasetRequest(String.Format("{0}/{1}/tables", powerBiApiUrl, datasetId), "GET", token);
var responseContent = GetResponse(request);
var json = new JavaScriptSerializer();
response = (Tables)json.Deserialize(responseContent, typeof(Tables));
}
catch (Exception ex)
{
Console.WriteLine("Data: "+ex.Data);
Console.WriteLine("Message: " + ex.Message);
Console.WriteLine("Source: " + ex.Source);
Console.WriteLine("TargetSite: " + ex.TargetSite);
Console.WriteLine("StackTrace: " + ex.StackTrace);
}
I have encountered this problem too, but my research shows that unless the dataset was created through the Power BI Rest API, you cannot list the tables or push data to the dataset. This is unfortunate, hopefully this will change with the ongoing speedy evolution Power BI continues to go through, but I can think of reasons why it won't.
One of the biggest side effects of this is you miss out on using measures on a dataset created through the Rest API.
https://community.powerbi.com/t5/Developer/REST-API-and-Power-BI-Desktop/td-p/20891
https://msdn.microsoft.com/en-us/library/mt203556.aspx

Filter on a BindingSource : did the DataSource must be a DataTable

I have a DataGridView that I bind on a BindingSource.
The thing is, when I do a filter on it, it doesn't work.
Is it needed, to add Filter on a BndingSource DataSource, that the DataSource is a DataTable.
For now, it is jst a list of Object, but I can return a DataTable.
Should I change it or not?
bindingSource1.DataSource = Echange.GetListEchange(contextExecution.ChaineConnexion, criteres);
GetListEchange, return a list of Echange.
But with this, the filter doesn't work :
bindingSource1.Filter = "ec.date_echange IS NULL";
So, this will work if I return a DataTable instead?
Hope I can use Filter without returning a DataTable but, if I have to do it, no problem.
Generate the DataTable :
vRequete += vFrom + " " + vWhere.Trim().TrimEnd("AND".ToCharArray()) + " " + vOrderBy;
vTable = vTarget.RenvoiOneTable(vRequete);
RenvoieOneTable is a method providing by Oracle. The code is :
public override DataTable RenvoiOneTable(string piRequest)
{
DataTable poDatable = null;
try
{
poDatable = ChargeDataSet(piRequest).Tables[0];
}
catch (OracleException ThisException)
{
throw new BaseDonneesException(ThisException.Message);
}
catch (Exception ThisExcept)
{
throw new BaseDonneesException(ThisExcept.Message);
}
return poDatable;
}
public override DataSet ChargeDataSet(string piRequest)
{
DataSet poDataset = null;
try
{
//Ouverture de la connection
Connexion.Open();
//Initialisation de la commande
Command.CommandType = CommandType.Text;
//Mise en place dans la variable po_datasets de l'identifiant et du
//dataset voulu
Command.CommandText = piRequest;
using (OracleDataAdapter vAdapter = new OracleDataAdapter(Command))
{
poDataset = new DataSet();
vAdapter.Fill(poDataset);
}
}
catch (OracleException ThisException)
{
throw new BaseDonneesException(ThisException.Message);
}
catch (Exception ThisExcept)
{
throw new BaseDonneesException(ThisExcept.Message);
}
finally
{
if (Connexion.State == ConnectionState.Open)
{
Connexion.Close();
}
}
//Envoye du tableau de DataSet
return poDataset;
}
Thank you.
A DataGridView can only deal with one set of 2D information (i.e., one DataTable). Although it is not bad to rely on a Binding variable (actually, it is recommended by MSDN), the reality is that the DataGridView only relates to one of its DataTables (in case of having more than one in the binding source, you would have to specify the one you want to be the DataSource via the DataMember property).
Thus, any change you want to do in the DataSource has to be done in the given DataTable, in case of considering a binding source; and thus the behaviour you are observing is the expected one.

WCF Data Client does not send entity properties values

When i try to send an instance of MULTIMEDIA type, with
hasStream="true"
property set to true, the WCF Data Server seems not to receive entity data.
On the client side i iterate over a collection of objects and i try to send them to another wcf data service. The reference to the "other wcf data service" is:
this.centralCtx
Also i set the saved stream for the each new entity and initialize all properties copying them from the source entity:
foreach (LOCAL_TYPE localObject in localObjects)
{
if (entityName == "MULTIMEDIA")
{
CentralService.ARTICOLI article = null;
CentralService.MULTIMEDIA multimedia = new CentralService.MULTIMEDIA();
LocalService.MULTIMEDIA lMultimedia = localObject as LocalService.MULTIMEDIA;
multimedia.ID_MULTIMEDIA = lMultimedia.ID_MULTIMEDIA;
multimedia.DATA_CREAZIONE = lMultimedia.DATA_CREAZIONE;
multimedia.DATA_ULTIMA_MODIFICA = lMultimedia.DATA_ULTIMA_MODIFICA;
multimedia.ARTICOLO_ID = lMultimedia.ARTICOLO_ID;
this.centralCtx.TryGetEntity(
new Uri(this.centralCtx.BaseUri + "ARTICOLI('" + multimedia.ARTICOLO_ID
+ "')", UriKind.Absolute), out article);
article.MULTIMEDIA.Add(multimedia);
this.centralCtx.AddRelatedObject(article, "MULTIMEDIA", multimedia);
DataServiceStreamResponse streamResponse = this.localCtx.GetReadStream(localObject);
this.centralCtx.SetSaveStream(multimedia, streamResponse.Stream,
true, "image/jpeg", "");
//this.centralCtx.UpdateObject(article);
}
else {
CENTRAL_TYPE cloned = DbHelper.FlatCloneFromType<LOCAL_TYPE, CENTRAL_TYPE>
(localObject, centralCtx);
this.centralCtx.AddObject(entityName, cloned);
}
}
try
{
this.centralCtx.SaveChanges();
Notify(progressAction, "Exported table " + entityName, null);
successAction(this.Log);
}
catch (Exception ex)
{
Notify(progressAction, "Error exporting table " + entityName, ex);
this.synchResult = SynchResultType.Error;
exceptionAction(ex);
}
This is change interceptor code:
[ChangeInterceptor("MULTIMEDIA")]
public void OnChangeMultimedia(MULTIMEDIA changedObject, UpdateOperations op)
{
switch (op)
{
case UpdateOperations.Add:
if(changedObject.ID_MULTIMEDIA == null)
changedObject.ID_MULTIMEDIA = Guid.NewGuid().ToString();
changedObject.STATO_INTERNO = "TRASFERITO";
changedObject.DATA_ULTIMA_MODIFICA = changedObject.DATA_ULTIMA_MODIFICA == null
? DateTime.Now.ToLocalTime() : changedObject.DATA_ULTIMA_MODIFICA;
this.CurrentDataSource.SaveChanges();
break;
default: break;
}
}
All the properties of changedObject on the server inside MULTIMEDIA change interceptor are always null. Why?
I finally got the answer.
The sending of an entity marked with the attribute hasStream implies two requests.
The first is a POST during which the server creates a record in the database and save the file on the file system.
The second is a MERGE during which the client performs an update to the ID passed from the server
That's why during the first request to the server all the properties of the object are null.

Categories

Resources