Jsonb function works through pgAdmin but won't work through Npgsql in C# - npgsql

I need to do an update in a jsonb field in one of my tables, which I can do successfully through the following command:
update tab set draft = jsonb_set(draft, '{ result }', jsonb '"yes"', true) WHERE id=...
which updates the jsonb column to {"result": "yes"}.
When I try to call the following code in C#, there is no error, but the row is not updated.
string query = "update tab set draft=jsonb_set(draft, '{ result }', jsonb '\"yes\"', true) WHERE id=#uid;";
using (var cmd = new NpgsqlCommand(query, pgsqlConnection))
{
cmd.Parameters.AddWithValue("uid", 1);
var ret = cmd.ExecuteNonQuery();
}
I'd really appreciate any insight on why this fails to update the the table.
Npgsql version is v6.0.0

You have to configure Json.NET Type plugin before use, like this:
using Npgsql;
// Place this at the beginning of your program to use Json.NET everywhere (recommended)
NpgsqlConnection.GlobalTypeMapper.UseJsonNet();
// Or to temporarily use JsonNet on a single connection only:
conn.TypeMapper.UseJsonNet();
For more details, see https://www.npgsql.org/doc/types/jsonnet.html

Related

How can we initialize DataChangeDetectionPolicy using .netsdk?

I have created a new index that is populated using an indexer. The indexer's datasource is a SQL view that has a Timestamp column of type datetime. Since we don't want a full reindexing each time the indexer runs, this column should be used to determine which data have changed since the last indexer run.
According to the documentation we need to create or update the datasource by setting the HighWatermarkColumnName and ODataType to the DataChangeDetectionPolicy object. The example in the documentation uses the REST API and there is also way to do it using the azure search portal directly.
However I want to do it using .netsdk and so far I haven't been able to do so. I am using Azure.Search.Documents(11.2.0 - beta.2). Here is the part of the code I use to create the datasource:
SearchIndexerDataSourceConnection CreateIndexerDataSource()
{
var ds = new SearchIndexerDataSourceConnection(DATASOURCE,
SearchIndexerDataSourceType.AzureSql,
this._datasourceConStringMaxEvents,
new SearchIndexerDataContainer(SQLVIEW));
//ds.DataChangeDetectionPolicy = new DataChangeDetectionPolicy();
return ds;
}
The commented code is what I tried to do to initialize the DataChangeDetectionPolicy but there is no ctor exposed. Am I missing something?
Thanks in advance.
Instead of using DataChangeDetectionPolicy, you will need to use HighWaterMarkChangeDetectionPolicy which is derived from DataChangeDetectionPolicy.
So your code would be something like:
ds.DataChangeDetectionPolicy = new HighWaterMarkChangeDetectionPolicy("Timestamp");

Use stored procedure in c# ef

I have a stored procedure in SQL Server:
Create PROCEDURE SPLogCountInUser
(#ManegerID int)
AS
SELECT COUNT(*) AS LogDone
FROM vw_UserApprove
WHERE UserMasterID = #ManegerID AND UserState = 0
I want to use this procedure to show me the output of this stored procedure in my WPF Entity Framework.
I have a label in my WPF window that I want it to show me the out put of above procedure. My code is like this, but it does not work:
HadishDataBaseEntities database = new HadishDataBaseEntities();
var All = database.SPLogCountInUser(HadishCode.gUserID);
lbl_Log.Content = All.ToList();
What does "not work" mean? Are you getting a compilation error, a runtime exception or just an unexpected result? Please always specify this when you aska question.
And what's the return type of your SPLogCountInUser method? If it is an IEnumerable, you could set the Content property of the Label to the string representation of the first item:
HadishDataBaseEntities database = new HadishDataBaseEntities();
var All = database.SPLogCountInUser(HadishCode.gUserID).ToList();
if(All != null && All.Count > 0)
lbl_Log.Content = All[0].ToString();
You can do that like this:
HadishDataBaseEntities database = new HadishDataBaseEntities();
var All = database.Database.SqlQuery<int>("SPLogCountInUser #ManegerID", HadishCode.gUserID);
lbl_Log.Content = All.First(); //Your stored procedure will always return one row, so we don't need ToList(), additionally the label will not show the actual value if you set its content to a List.
I think .ToList(); must be added if you want your SP get some meanful value.
I made such mistake by missing .ToList() and failed to get anything even though I know the SQL invoke is correct.
But after adding .ToList(); then return value is a List and you can find your value.

Migrating working ServiceStack to live causes Unable to cast object of type 'System.Byte' to type 'System.String'

I have developed a ServiceStack API, using ORMLite based on a SQL Server. The app works perfectly pointing at both my local SQL database and an Azure database. Happy Days!
I have now tried to move this solution to the live server which has it's own local copy of the same database and I am getting strange results. The error is:
Error Code: InvalidCastException
Message: Unable to cast object of type 'System.Byte' to type 'System.String'.
[EMEM: 1/16/2014 11:49:29 AM]: [REQUEST: {Equipment:DP112}]
System.InvalidCastException: Unable to cast object of type 'System.Byte' to type 'System.String'. at lambda_method(Closure , Object , Object ) at
ServiceStack.OrmLite.OrmLiteDialectProviderBase`1.SetDbValue(FieldDefinition fieldDef, IDataReader dataReader, Int32 colIndex, Object instance) at
ServiceStack.OrmLite.ReadExtensions.ExprConvertToList[T](IDataReader dataReader) at ServiceStack.OrmLite.OrmLiteResultsFilterExtensions.ExprConvertToList[T](IDbCommand dbCmd, String sql) at
ServiceStack.OrmLite.ReadConnectionExtensions.Exec[T](IDbConnection dbConn, Func`2 filter) at
ViewPoint.EquipmentService.Get(EMEM request) at
ServiceStack.Host.ServiceRunner`1.Execute(IRequest request, Object instance, TRequest requestDto)
I have checked the database schemas and they look identical.
This is the code that works on 2 out of the 3 databases quite happily but not the third.
public object Get(EMEM request)
{
var dbFactory = new OrmLiteConnectionFactory(WebConfigurationManager.ConnectionStrings["db"].ToString(), SqlServerDialect.Provider);
using (IDbConnection db = dbFactory.OpenDbConnection())
{
if (request.Equipment == null)
{
List<EMEM> results = db.Select<EMEM>();
return results;
}
else
{
List<EMEM> results = db.Select<EMEM>(p => p.Where(ev => ev.Equipment == request.Equipment));
return results;
}
}
}
I can literally fix the problem by pointing the connection string at the azure database which tends to suggest it's database related(?)
Extra Information:
I have also written a put method which updates a row in the database and that works fine.
On 2 of the servers EMEM is a table but on the third, where it doesn't work, it's a View.
Can anyone suggest where to start looking for this problem?
UPDATE: I have now created a View on my local development database so it should now be identical to the live database. I was expecting this to break the local dev site but it hasn't... :(
BINGO! FIXED IT!
IT WAS linked to the View, but it wasn't the View's fault....
The view was looking at a table with different data types against most of the values. The demo table I was working against had all the columns set to String!
So, look out when people give you "demo tables, with identical data to the live" to develop against.
They aren't always identical!!
HTH

Indexing PDF documents with addtional search fields using SolrNet?

I found this article useful when indexing documents, however, how can I attach additional fields so I can pass in, say, the ID of the document in our database for use in displaying the search results? I thought by using the Fields (Of the ExtractParameters class) property I could index additional data with the document, but that doesn't seem to work or that is not its function.
Example code:
var solr = ObjectLocator.Instance.Resolve<ISolrOperations<IndexDocument>>();
var guid = Guid.NewGuid().ToString();
using (var fileStream = System.IO.File.OpenRead(Server.MapPath("~/files/") + "greenroof.pdf"))
{
var response =
solr.Extract(
new ExtractParameters(fileStream, "greenRoof1234")
{
ExtractFormat = ExtractFormat.Text,
ExtractOnly = false,
Fields = new[] { new ExtractField("field1", "value1"), new ExtractField("field2", "value2") }
});
}
#aitchnyu is correct, passing the values via the literal.field=value method is the correct way to do this.
However, according to this post on ExtractingRequestHandler support in the SolrNet Google Group, there was a bug with the ExtractParameters.Fields not working properly. This was fixed in the 0.4.0.X versions of SolrNet. Please make sure you are using one of the latest versions of SolrNet. You can obtain that by one of the following means:
Project Site Downloads
NuGet PreRelease Package
Also that discussion has some good examples of using the ExtractingRequestHandler in SolrNet as well as a workaround for adding the additional field values if you cannot upgrade to a newer version of SolrNet.
This is sufficient: http://wiki.apache.org/solr/ExtractingRequestHandler#Literals .
In general use a literal.field=value while uploading.
It turned out not to be an issue with SOLRNet, but my knowledge of SOLR, in general. I needed to specify the fields in my schema. After i added the fields to my schema they were visible in my SOLR query.

MiniProfiler - SqlParameter

I am using the latest version of the MiniProfiler, everything is setup and working as I would expect. My only issue is that SqlParameters are not being displayed.
For example, I am running a stored procedure:-
var cmd = dbcon.CreateCommand();
cmd.CommandText = "USP_Admin_Subscription_List";
cmd.CommandType = CommandType.StoredProcedure;
// parameters
cmd.Parameters.Add(new SqlParameter("#UserRef", SqlDbType.NVarChar) { Value = customerRef });
When this executes I see the SQL in the MiniProfiler display but I do not see the Parameter #UserRef nor it's value.
Is this possible? It would be great to see the value so I can ensure the correct value is being passed.
I am using MVC 3
Any advice would be welcomed.
Cheers,
J
Old questions, but just in case anyone else is looking for the answer to this:
The sample code has:
// different RDBMS have different ways of declaring sql parameters - SQLite can understand inline sql parameters just fine
// by default, sql parameters won't be displayed
MiniProfiler.Settings.SqlFormatter = new StackExchange.Profiling.SqlFormatters.InlineFormatter();
You need to change it to:
MiniProfiler.Settings.SqlFormatter = new StackExchange.Profiling.SqlFormatters.SqlServerFormatter();
And your parameters will appear.

Resources