I'm trying to add MiniProfiler to my DB2 connections. Below is my simplified code.
public void InitializeConnection()
{
DB2Connection cnn = new DB2Connection("connection String");
var profiler =
new StackExchange.Profiling.Data.ProfiledDbConnection(cnn, MiniProfiler.Current);
IDbCommand c = new DB2Command();
c.Connection = profiler ;
}
My problem is occurring in the last line where the profiler is assigned to the DB2Command's Connection property. I'm getting the below error.
Unable to cast object of type 'StackExchange.Profiling.Data.ProfiledDbConnection' to type 'IBM.Data.DB2.DB2Connection'
I've tried a couple of different casting ideas and nothing has worked out.
I think you're going at it backwards. You're assigning the connection to the ProfiledDbConnection class (as seems to be correct, based on the docs on the MiniProfiler website).
However, you're then creating a DB2-specific command object, and trying to assign the ProfiledDbConnection class to the connection object.
I think what you want to do is call profiler.CreateDbCommand(), which will create a ProfiledDbCommand object that uses the DB2Command class "under the covers".
The DB2Command.Connection property is of the type DB2Connection (as the error message helpfully tells you). Try DbConnection instead:
c.DbConnection = profiler
More in the manual
Related
I have the following code, where "CI_COL" is of type citext (https://www.postgresql.org/docs/current/static/citext.html)
String str = "testING";
int countBad = context.fetchCount(select(Tables.MY_TABLE.CI_COL)
.from(Tables.MY_TABLE)
.where(Tables.MY_TABLE.CI_COL.eq(str)));
int countGood = context.fetchCount(select(Tables.MY_TABLE.CI_COL)
.from(Tables.MY_TABLE)
.where(Tables.MY_TABLE.CI_COL.eq(cast(str, new DefaultDataType<>(SQLDialect.POSTGRES, String.class, "citext")))));
The first query returns 0, and the second query correctly returns > 0.
It took me a long time to track down the root cause, because when the first query was printed (or found in the DEBUG logging), it seemed to execute in the terminal just fine.
Once I got down to the statement level and actually started binding values, that's where the root cause seemed to be. It seems to be an issue (or on purpose) in the postgres driver. This post illustrates the binding issue with citext: https://www.postgresql.org/message-id/CAJFs0QB90bo0vWw5pZcw0c%3DLjOcOX04qPEM4nSd6uY7-T2r5hA%40mail.gmail.com
Is it possible to fix this at the JOOQ level, by having JOOQ automatically perform a cast on all right hand side values for a specific column?
Side note
new DefaultDataType<>(...)
Ghasp! You're using internal API :)
Correct solution
The correct way to introduce new data types in jOOQ is to use a Converter, or in this case a data type Binding:
http://www.jooq.org/doc/latest/manual/sql-building/queryparts/custom-bindings
While most Binding method implementations would simply delegate to jOOQ's DefaultBinding, you can override the sql() method (which generates the bind variable's SQL string) to this:
#Override
public void sql(BindingSQLContext<JsonElement> ctx) throws SQLException {
ctx.render().sql("?::citext");
}
I have create a project with eclipse and added the postgis-jdbc-2.1.7.jar , postgresql-9.4.1208.jre6.jar to my class path.
Then I tried the example from the postgis documentation see example in order to connect to the db.
The following lines produce an error:
/*
* Add the geometry types to the connection. Note that you
* must cast the connection to the pgsql-specific connection
* implementation before calling the addDataType() method.
*/
((org.postgresql.PGConnection)conn).addDataType("geometry",Class.forName("org.postgis.PGgeometry"));
((org.postgresql.PGConnection)conn).addDataType("box3d",Class.forName("org.postgis.PGbox3d"));
The error is the following:
The method addDataType in the type connection is not applicable for the arguments
Has anyone else faced the same error?
Any ideas?
Is this a run-time error? Perhaps Class.forName() is returning null. Try making a static reference to the class by replacing the call to "Class.forName()" with "org.postgis.PGgeometry.class" which will fail at compile time instead of run time if your classpath is off.
At the moment i have an application (web/silverlight) where the connectionstring for my ObjectContext is dynamic. It is based on how a user logs in because each of my customers have their own database. ie.. username#domain. I'm trying to find a way to use the EFContextProvider which would be by either passing the ObjectContext through the constructor, or by overriding the GetConnectionString, which sadly both aren't supported.
Is there a way to accomplish this, or can i download the source for the EFContextProvider somewhere so i can implement it myself ?
Thanks in advance.
This question was posted by Marcel on our IdeaBlade forums. I am reposting the question and answer here since I think it will be useful to the Breeze Stack Overflow community.
You shouldn't have to download the source and modify it for such a simple thing. And now you won't have to.
We've pushed to GitHub a simple update to EFContextProvider. This change will appear in the next Breeze Runtime version (> 0.81.2).
Where EFContextProvider used to create the 'T' (your ObjectContext/DbContext) as follows:
_context = new T();
It now calls upon a virtual method, T CreateContext() instead, whose default implementation is:
protected virtual T CreateContext() {
return new T();
}
Override and replace that in your EFContextProvider subclass and you will be able to make your context of type 'T' just the way you like it.
N.B.: The base EFContextProvider will still do a little post-creation configuration to make sure it behaves as we expect; we don't want the context doing any lazy loading or creating proxies.
So if 'T' is an ObjectContext, the provider will do this:
objCtx.ContextOptions.LazyLoadingEnabled = false;
and if 'T' is a DbContext it will do this:
dbCtx.Configuration.ProxyCreationEnabled = false;
dbCtx.Configuration.LazyLoadingEnabled = false;
I downloaded the source and added a constructor to the
EFContextProvider which accepts an instance of T to be able to use an
existing ObjectContext/DbContext which works like a charm.
Marcel figured it out by himself and answered his own question on our forum.
The CreateContext virtual method, mentioned by Ward, is now available in v 0.83.2
I'm trying to integrate NHibernate.Validator with ASP.NET MVC client side validations, and the only problem I found is that I simply can't convert the non-interpolated message to a human-readable one. I thought this would be an easy task, but turned out to be the hardest part of the client-side validation. The main problem is that because it's not server-side, I actually only need the validation attributes that are being used, and I don't actually have an instance or anything else at hand.
Here are some excerpts from what I've been already trying:
// Get the the default Message Interpolator from the Engine
IMessageInterpolator interp = _engine.Interpolator;
if (interp == null)
{
// It is null?? Oh, try to create a new one
interp = new NHibernate.Validator.Interpolator.DefaultMessageInterpolator();
}
// We need an instance of the object that needs to be validated, se we have to create one
object instance = Activator.CreateInstance(Metadata.ContainerType);
// we enumerate all attributes of the property. For example we have found a PatternAttribute
var a = attr as PatternAttribute;
// it seems that the default message interpolator doesn't work, unless initialized
if (interp is NHibernate.Validator.Interpolator.DefaultMessageInterpolator)
{
(interp as NHibernate.Validator.Interpolator.DefaultMessageInterpolator).Initialize(a);
}
// but even after it is initialized the following will throw a NullReferenceException, although all of the parameters are specified, and they are not null (except for the properties of the instance, which are all null, but this can't be changed)
var message = interp.Interpolate(new InterpolationInfo(Metadata.ContainerType, instance, PropertyName, a, interp, a.Message));
I know that the above is a fairly complex code for a seemingly simple question, but I'm still stuck without solution. Is there any way to get the interpolated string out of NHValidator?
Ok, so I know this is an old question, but I stumbled across this when trying to do the same thing, and it helped me get started - so I thought I would provide an answer.
I think the code in the question was on the right track but there are a couple of problems. The interpolator was not completely initialised with the ResourceManager and Culture details, and it doesn't seem to allow for the fact that you can only have one DefaultMessageInterpolator per validation attribute. Also, you don't need an instance of the object you are validating to get an interpolated message.
In the code in the question, where you are initialising the interpolator with the attribute value, you also need to initialise the interpolator with details of the ResourceManager to be used.
This can be done using the overloaded Initialize method on DefaultMessageInterpolator which has the following signature:
public void Initialize(ResourceManager messageBundle,
ResourceManager defaultMessageBundle,
CultureInfo culture)
The first parameter is a user-defined ResourceManager in case you want to use your own resource file for error messages, you can pass a null if you just want to use the default ResouceManager, the second parameter is the default ResourceManager - you can pass
new ResourceManager(
NHibernate.Validator.Cfg.Environment.BaseNameOfMessageResource,
Assembly.GetExecutingAssembly());
for this, the last parameter is the culture to use, (NHibernate.Validator comes with resource files with validation messages in several languages) - if you pass a null in to this it will just use CultureInfo.CurrentCulture
Lastly, you can only have one DefaultMessageInterpolator per attribute, so you will need to create a new DefaultMessageInterpolator for each validation attribute. You could make use of the DefaultMessageInterpolatorAggregator to handle this, or just roll your own.
I hope this helps someone.
Thanks for your help all--I'd upvote if I could. I just wanted to add that in addition to the first Initialize call on the DefaultMessageInterpolator that Stank illustrates, I also had to make a second different Initialize call to fully initialize it (I was getting some Null Reference Exceptions using only the first call). My code is as follows:
string interpolatedMessage = "";
DefaultMessageInterpolator interpolator = new DefaultMessageInterpolator();
interpolator.Initialize(null,
new ResourceManager(
NHibernate.Validator.Cfg.Environment.BaseNameOfMessageResource,
Assembly.Load("NHibernate.Validator")),
CultureInfo.CurrentCulture);
interpolator.Initialize(attribute as Attribute);
if (attribute is IValidator && attribute is IRuleArgs)
{
IValidator validator = attribute as IValidator;
IRuleArgs ruleArgs = attribute as IRuleArgs;
InterpolationInfo interpolationInfo = new InterpolationInfo(
validatableType,
null,
propertyName,
validator,
interpolator,
ruleArgs.Message);
interpolatedMessage = interpolator.Interpolate(interpolationInfo);
}
When executing the second line of this code Rhino Mocks throws an InvalidOperationException with a message "This action is invalid when the mock object is in replay state"
var mockScanner = MockRepository.GenerateMock<PortScanner>(null);
mockScanner.Expect((scanner => { scanner.Scan(null, null); }));
Stepping through the code in a debugger one can see the debugger run the method defined in the class and directly after control leaves this method the exception occurs.
This similar code in another test does work without issue
var mockView = MockRepository.GenerateMock<IScanView>(null);
mockView.Expect(view => { view.Close(); });
var controller = new ScanController(mockView);
controller.Exit();
mockView.VerifyAllExpectations();
The only difference that I can think of that might be of any consequense between theese two tests is that Exit is a member on an interface while Scan is a virtual member on a class
What am I missing?
Update
Further exploration has indicated that this is related to the way Rhino handles virtual methods. I am focusing mmy study of the documentation here now
The exception was caused because Rhino Mocks did not have the required level of access to the type in order to mock it properly. Granting internal access to the Rhino Mocks assembly using InternalsVisibleTo solved the problem.
It's noteworthy that this does not affect interfaces. I believe the reason for this is because the mocking framework needs to override the implementation on a class where there is none on an interface.
What happens if you remove the extra set of parentheses from the first expression?
var mockScanner = MockRepository.GenerateMock<PortScanner>(null);
mockScanner.Expect( scanner => { scanner.Scan(null, null); } );