SqlDataReader and method scope - c#-4.0

Why is data read from SqlDataReader not available to a method call?
I have a table, with 'id' as column in it.
When I make a query to database, it returns rows.
This code doesnt work (Says 'id' column doesnt exist):
con.Open();
SqlDataReader requestReader = cmd.ExecuteReader();
if (requestReader.HasRows)
{
DataTable requestTable = requestReader.GetSchemaTable();
request = ReadRequest(requestTable.Rows[0]);
}
con.Close();
while this one works:
con.Open();
SqlDataReader requestReader = cmd.ExecuteReader();
if (requestReader.HasRows)
{
DataTable requestTable = requestReader.GetSchemaTable();
var requestRow = requestTable.Rows[0];
request = new Request();
request.UniqueId = (string)requestRow["id"];
}
con.Close();

You are using DataReader.GetSchemaTable which returns a DataTable with all schema informations for a given table.
It has following columns:
ColumnName
ColumnOrdinal
ColumnSize
NumericPrecision
// .. 26 others
So you don't find your id-column which belongs to your table. That's why you get the error "'id' column doesnt exist". I doubt that your second approach works. I don't see why you need GetSchemaTable at all. You just have to advance the reader to the next record:
if (requestReader.HasRows && requestReader.Read())
{
int id = requestReader.GetInt32(requestReader.GetOrdinal("id"));
// ...
}

Related

Unable to fetch item in SharePoint List (threshold > 5000 ) through CSOM

I am trying to create a Windows Form for populating the information from SharePoint List into Windows Form. However, when I am trying to fetch the item from the list, it throws me an error message
An unhandled exception of type 'Microsoft.SharePoint.Client.PropertyOrFieldNotInitializedException' occurred in Microsoft.SharePoint.Client.dll
Additional information: The property or field has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested."
Here is the code for the same.
private void btn_populatecontainer_Click(object sender, EventArgs e)
{
var authManager = new AuthenticationManager();
ClientContext overviewlistClientcontext = authManager.GetWebLoginClientContext("Tenant URL");
var tenant = new Tenant(overviewlistClientcontext);
var siteProperties = tenant.GetSiteByUrl("SiteCollectionURL");
Web web = siteProperties.RootWeb;
List olist = web.Lists.GetByTitle("SiteOverviewList");
overviewlistClientcontext.Load(siteProperties);
overviewlistClientcontext.ExecuteQuery();
ListItemCollectionPosition position = null;
var page = 1;
do
{
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = #"<View Scope='Recursive'><RowLimit>4000</RowLimit><Query><Where><Eq><FieldRef Name='Site URL'/><Value Type='Text'>" + txtSite.Text + "</Value></Eq></Where></Query></View>";
camlQuery.ListItemCollectionPosition = position;
ListItemCollection listItems = olist.GetItems(camlQuery);
overviewlistClientcontext.Load(listItems);
overviewlistClientcontext.ExecuteQuery();
position = listItems.ListItemCollectionPosition;
DataTable dataTable = new DataTable();
DataRow dr;
DataColumn dc = new DataColumn("Site Owner");
dc.DataType = Type.GetType("System.String");
dataTable.Columns.Add(dc);
foreach (var listItem in listItems)
{
dr = dataTable.NewRow();
dr["Site Owner"] = listItem["Site Owner"];
dataTable.Rows.Add(dr);
}
OverViewListGrid.DataSource = dataTable;
OverViewListGrid.DataBindings
page++;*/
}
while (position != null);
}
}
}
I have debugged the code and it fails when it tries to execute query after fetching from Caml Query.
When CamlQuery gets executed, it doesn't work at all.
However, for the testing purpose, I have tried to fetch other columns and the code works if I try to fetch Title/Id Column directly using inbuilt functions (i.e. GetItembyID).
But even the second steps won't work if i use another column from the same list.
Can anyone help me with this?
To filter list items from list which over threshold, need use indexed column.
The Site URL need to be indexed column.
<Query><Where><Eq><FieldRef Name='Site URL'/><Value Type='Text'>" + txtSite.Text + "</Value></Eq></Where></Query>
Otherwise, you need get all items from SharePoint by pagination.
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = #"<View Scope='Recursive'><RowLimit>4000</RowLimit><Query></Query></View>";
Then, filter by Linq.
How I can filter a dataTable with Linq to datatable?
the exception says that You are trying to get value of a column that has not been initialized in the context. In order to get it You need to load it to the client context together with the list item collection. The simplest way to get all fields is to use 'FieldValuesAsText'. For Your code example the updated code would look like
.....
overviewlistClientcontext.Load(listItems, includes => includes.Include(i => i.FieldValuesAsText));
overviewlistClientcontext.ExecuteQuery();
position = listItems.ListItemCollectionPosition;
DataTable dataTable = new DataTable();
DataRow dr;
DataColumn dc = new DataColumn("Site Owner");
dc.DataType = Type.GetType("System.String");
dataTable.Columns.Add(dc);
foreach (var listItem in listItems)
{
dr = dataTable.NewRow();
dr["Site Owner"] = listItem.FieldValuesAsText["Site Owner"];
dataTable.Rows.Add(dr);
}
.....
Also please be aware that You should use internal name (not display name) of column to get the field value. So I suspect that the internal name for You column 'Site Owner' would be 'Site_x0020_Owner' so You should take it like:
dr["Site Owner"] = listItem.FieldValuesAsText["Site_x0020_Owner"];
In order to check what is the internal name of Your column, the easiest way is to enter edit page of Your column and the internal name will be part of the URL as one of the GET parameters

IllegalArgumentException: Table xyz does not exist in keyspace my_ks

I am developing an application, where I am trying to create a table if not exists and making a Query on it. It is working fine in normal cases. But for the first time , when the table is created , then when trying to Query the same table, the application is throwing :
IllegalArgumentException: Table xyz does not exist in keyspace my_ks
Same happens if I drop the table, and when my code recreates the table again.
For other cases, when the table exists, it is working fine. Is it some kind of replication issue, or should use a timeout from some time when the table is created for first time.
Following is the code snippet:
// Oredr 1: First this will be called
public boolean isSchemaExists() {
boolean isSchemaExists = false;
Statement statement = QueryBuilder
.select()
.countAll()
.from(keyspace_name, table_name);
statement.setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM);
try {
Session session = cassandraClient.getSession(someSessionKey);
ResultSet resultSet = null;
resultSet = session.execute(statement);
if (resultSet.one() != null) {
isSchemaExists = true;
}
} catch (all exception handling)
}
return isSchemaExists;
}
// Oredr 2: if previous method returns false then this will be get called
public void createSchema(String createTableScript) {
Session session = cassandraClient.getSession(someSessionKey);
if (isKeySpaceExists(keyspaceName, session)) {
session.execute("USE " + keyspaceName);
}
session.execute(createTableScript);
}
//Oredr 3: Now read the table, this is throwing the exception when the table
// is created for first time
public int readTable(){
Session session = cassandraClient.getSession(someSessionKey);
MappingManager manager = new MappingManager(session);
Mapper<MyPojo> mapper = manager.mapper(MyPojo.class);
Statement statement = QueryBuilder
.select()
.from(keyspaceName, tableName)
.where(eq("col_1", someValue)).and(eq("col_2", someValue));
statement.setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM);
ResultSet resultSet = session.execute(statement);
result = mapper.map(resultSet);
for (MyPojo myPojo : result) {
return myPojo.getCol1();
}
}
In isSchemaExists function use system.tables.
SELECT * FROM system.tables WHERE keyspace_name='YOUR KEYSPACE' AND table_name='YOUR TABLE'
Corresponding Java Code:
Statement statement = QueryBuilder
.select()
.from("system", "tables")
.where(eq("keyspace_name", keyspace)).and(eq("table_name", table));
It seems like in isSchemaExists you are using actual table and keyspace which will not exist when dropped or not created. That's the reason it is throwing you error table does not exist.

Lose Properties when convert Cassandra column to java object

I use spring-data-cassandra-1.2.1.RELEASE to operate Cassandra database. Things all go well .But recent days I got a problem, when I using the code to get data:
public UserInfoCassandra selectUserInfo(String passport) {
Select select = QueryBuilder.select().from("userinfo");
select.setConsistencyLevel(ConsistencyLevel.QUORUM);
select.where(QueryBuilder.eq("passport", passport));
UserInfoCassandra userinfo = operations.selectOne(select,
UserInfoCassandra.class);
return userinfo;
}
there were many properties in userinfo , but I just get two the passport and uid properties.
I debug into the method,got that the data getting from db is right,all properties were ready.but when converting them to a java object ,some disappear.. the converting code:
protected <T> T selectOne(Select query, CassandraConverterRowCallback<T> readRowCallback) {
ResultSet resultSet = query(query);
Iterator<Row> iterator = resultSet.iterator();
if (iterator.hasNext()) {
Row row = iterator.next();
T result = readRowCallback.doWith(row);
if (iterator.hasNext()) {
throw new DuplicateKeyException("found two or more results in query " + query);
}
return result;
}
return null;
}
the row data is right ,but the result is wrong, who can help ?
Most probably your entity class and it's corresponding relational model are mismatched.

QueryExpression with no results in Dynamics CRM plugin

I wrote the following function to get the SharePointDocumentLocation records regarding an account or contact. However, even though I provide an id which most definitely has got a SPDL record associated the result of a count on the EntityCollection that is returned is alway 0. Why does my query not return SPDL records?
internal static EntityCollection GetSPDocumentLocation(IOrganizationService service, Guid id)
{
SharePointDocumentLocation spd = new SharePointDocumentLocation();
QueryExpression query = new QueryExpression
{
EntityName = "sharepointdocumentlocation",
ColumnSet = new ColumnSet("sharepointdocumentlocationid"),
Criteria = new FilterExpression
{
Conditions =
{
new ConditionExpression
{
AttributeName = "regardingobjectid",
Operator = ConditionOperator.Equal,
Values = { id }
}
}
}
};
return service.RetrieveMultiple(query);
}
The following code does work
using System;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using System.ServiceModel.Description;
using System.Net;
using Microsoft.Xrm.Sdk.Query;
namespace CRMConsoleTests
{
class Program
{
static void Main(string[] args)
{
ClientCredentials credentials = new ClientCredentials();
credentials.Windows.ClientCredential = CredentialCache.DefaultNetworkCredentials;
Uri orgUri = new Uri("http://localhost/CRMDEV2/XRMServices/2011/Organization.svc");
Uri homeRealmUri = null;
using (OrganizationServiceProxy service = new OrganizationServiceProxy(orgUri, homeRealmUri, credentials, null))
{
//ConditionExpression ce = new ConditionExpression("regardingobjectid", ConditionOperator.Equal, new Guid(""));
QueryExpression qe = new QueryExpression("sharepointdocumentlocation");
qe.ColumnSet = new ColumnSet(new String[] { "sharepointdocumentlocationid", "regardingobjectid" });
//qe.Criteria.AddCondition(ce);
EntityCollection result = service.RetrieveMultiple(qe);
foreach (Entity entity in result.Entities)
{
Console.WriteLine("Results for the first record: ");
SharePointDocumentLocation spd = entity.ToEntity<SharePointDocumentLocation>();
if (spd.RegardingObjectId != null)
{
Console.WriteLine("Id: " + spd.SharePointDocumentLocationId.ToString() + " with RoId: " + spd.RegardingObjectId.Id.ToString());
}
}
Console.ReadLine();
}
}
}
}
It retrieves 4 records, and when I debug the plugincode above it retrieves 3 records.
Everything looks good with your QueryExpression, although I'd write it a little more concise (something like this):
var qe = new QueryExpression(SharePointDocumentLocation.EntityLogicalName){
ColmnSet = new ColumnSet("sharepointdocumentlocationid"),
};
qe.Criteria.AddCondition("regardingobjectid", ConditionOperator.Equal, id);
Because I don't see anything wrong with the QueryExpression that leads me with two guesses.
You're using impersonation on the IOrganizationService and the impersonated user doesn't have rights to the SharePointDocumentLocation. You won't get an error, you just won't get any records returned.
The id you're passing in is incorrect.
I'd remove the Criteria and see how many records you get back. If you don't get all of the records back, you know your issue is with guess #1.
If you get all records, add the regardingobjectid to the ColumnSet and retrieve the first record without any Criteria in the QueryExpression, then call this method passing in the id of the regardingobject you returned. If nothing is received when adding the regardingobjectid constraint, then something else is wrong.
Update
Since this is executing within the delete of the plugin, it must be performing its cascade deletes before your plugin is firing. You can try the Pre-Validation.
Now that I think of it, it must perform the deletion of the cascading entities in the Validation stage, because if one of them is unable to be deleted, the entity itself can't be deleted.

SliceQuery in Hector API for cassandra DB throws HInvalidRequestException: InvalidRequestException(why:Key may not be empty)

I have username and password as the columns of a ColumnFamily keyed with userName.
create column family TestUserInfo with comparator = UTF8Type with
column_metadata = [{column_name: username, validation_class:UTF8Type},
{column_name: password, validation_class:UTF8Type} ];
The following code works fine when the key is present in the db. Whereas throws me.prettyprint.hector.api.exceptions.HInvalidRequestException: InvalidRequestException(why:Key may not be empty) when the key is not present.
SliceQuery<String, String, String> sliceQuery = HFactory.createSliceQuery(cassandraDBObject.getKeyspace(), StringSerializer.get(), StringSerializer.get(), StringSerializer.get());
sliceQuery.setColumnFamily("TestUserInfo");
sliceQuery.setKey(userName);
sliceQuery.setColumnNames("username", "password");
String userNameFromDB = null;
String passwordFromDB = null;
try {
[Error here -->] QueryResult<ColumnSlice<String, String>> queryResult = sliceQuery.execute();
ColumnSlice<String, String> resultCol = queryResult.get();
System.out.println(resultCol);
userNameFromDB = resultCol.getColumnByName("username").getValue();
passwordFromDB = resultCol.getColumnByName("password").getValue();
} catch (Exception e) {
e.printStackTrace();
}
Can you ppl tell me where I am going wrong? Or is this the expected behaviour? If so then how can i check for empty results? Say I am checking login information from db. Then if the userName(Key) is not in db then i need to get an empty result right?
Thanks!
Sure sounds to me like it's complaining that you're giving it an empty or null userName.

Resources