I'm using LINQ to SQL to call some reporting stored procedures.
Each stored procedure returns a class which accepts some input parameters, for example:
public partial class csp_WeekCommencingListResult
{
public static IEnumerable<csp_WeekCommencingListResult> GetAll(int? masterTrackingGroupId)
{
using (var dataContext = OscaDataContext.CreateWithCustomTimeOut())
{
return dataContext
.csp_WeekCommencingList(masterTrackingGroupId)
.ToList();
}
}
}
How could I cache the result of the stored procedure for the passed parameters?
For example, when 1 is passed to this stored procedure, its result should be cached for a day.
Any thoughts? is there any framework I can use? or I have to build my own custom cache manager per stored procedure using the .NET Cache object?
Thanks,
You should probably add caching at a higher level, for example in the code that is calling this code.
Try to figure out a good caching strategy that works with your project.
And when it comes to cache managers, I usually use the ICacheManager from Microsoft EnterpriseLibrary Caching which I property inject with some dependency injection framework like Castle or StructureMap. That way I can run different configurations for different environments (dev, test, prod etc).
Related
I'm getting the following exception:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'answerRepository': Invocation of init method failed; nested exception is org.springframework.data.couchbase.core.UnsupportedCouchbaseFeatureException: Repository uses N1QL
I'm using Spring 4.2.0.RELEASE with spring-data-couchbase 2.0.0.M1 against Couchbase 2.5.1 enterprise edition (build-1083)
I can't see any explanation in the doc for this error.
Here is the repository:
public interface AnswerRepository extends BaseRepository<Answer, String> {
final static String DESIGN_DOCUMENT = "answers";
#View(viewName = "answers_by_quizId_startTime", designDocument = DESIGN_DOCUMENT)
public List<Answer> findByQuizIdAndStartTime(String quizId, long startTime);
Answer findByUuid(String uuid);
}
#NoRepositoryBean
public interface BaseRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
}
Maybe my Couchbase server does not support this feature, whereas my repository expects it.
I might need to code my repository differently.
It's too bad it doesn't say which method is the invalid one here.
Or it is my using of the CrudRepository in the base class ?
I wonder how to find out which views it expects to find in my Couchbase server.
Repositories in Spring Data Couchbase 2.0 rely almost exclusively on Views and N1QL. A good chunk of the new features in this version are made possible by N1QL, which is now the default mechanism Spring Data uses for things like "query derivation" (implementing a repository method by producing some sort of query that is derived from the method name).
Couchbase Server 2.5.1 doesn't have access to N1QL (which came with Couchbase Server 4.0 and of course also in the brand new 4.1 version).
If you want Spring Data to implement findByUuid for you, you'll have to annotate that method with #View and create the appropriate view that emits uuids from your Answer documents.
View query derivations are heavily restricted and give you more work since you have to write the correct map function:
a repository method based on a view can only query with one criteria.
you have to create your view correctly, emitting the correct keys corresponding to the criteria you'll query with.
you have to create one view per entity class, restricting the view to only emit if the "_class" field in the JSON matches said entity (note: this field can be renamed in the configuration so make sure to use the relevant one).
So that means that your findByQuizIdAndStartTime cannot work either. You may have to implement this (and maybe findByUuid) in the BaseRepository, relying on the CouchbaseTemplate and using its findByView method (or even queryView as a last resort).
The UnsupportedCouchbaseFeatureException is mentioned in the M1 doc chapter 7 (on N1QL based querying).
See also the section on view query derivation further down the documentation.
I have a web application that uses linq-to-sql queries (will soon be upgraded to linq-to-EF compiled queries) and for which there's data context and a database already in place. I want to create a demo version of the application and for the demo, I want to use an entirely different database file but that will have the same tables. So in essence, I'll have the same data structure for two different databases: one database for logged-in users and one database for demo users. I want to reuse many of the queries I've already written; they look like this:
public class FruitQueries
{
public List<SomeObjectModel> MyQuery(list of parameters)
{
using (MyDataContext TheDC = new MyDataContext())
{
var TheQueryResult = (from f in TheDC.Fruits
......).ToList();
return TheQueryResult;
}
}
public List<SomeObject> AnotherQuery(some other parameters) {...}
}
Now I think I know that this calls for dependency injection where the data context is passed in as a parameter but I'm not sure on the syntax. How do you reuse queries using dependency injection to make them work on two different databases? Right now I'm using a using statement and I want to keep this pattern; is that possible if I inject the DC as a parameter?
Thanks.
Since you already have a lot of code in place, probably the simplest thing to do is to inject a factory:
public interface IMyDataContextFactory
{
MyDataContext CreateNewContext();
}
All the code will roughly stay the same:
public List<SomeObjectModel> MyQuery(params)
{
using (var TheDC = this.factory.CreateNewContext())
{
var TheQueryResult = (from f in TheDC.Fruits
......).ToList();
return TheQueryResult;
}
}
You can let the injected IMyDataContextFactory decide how to construct a MyDataContext instance (based on the user). This would be trivial.
In the end it will probably be better to inject a MyDataContext (or an abstraction such as IUnitOfWork) into consumers, but this changes everything completely. Since this class is passed in from the outside, the consumer isn't responsible anymore for disposing it, but someone else is. Although disposing such instance isn't that hard with most DI container. It gets harder though when you want to share the same MyDataContext instance over multiple consumers (within the same web request for instance) and where do you call SubmitChanges?
Elaborating the previous answer
What you can do, is provide the connectionstring to the DC (would this qualify as contructor injection?)
using (MyDataContext TheDC = new MyDataContext(this.factory.CreateConString()))
This way, disposal is still handled by the consumer and you can continue your Using() approach. Your factory can read the two different connectionstrings from your webconfig and determine the right one to use, based on the user. (not that trivial as it may seem)
PS: I think the quickest way is to deploy the demo application to a different URL so they can have a separate web.config and you do not need to code anything but that does not answer your question.
I have build my site using entity and repository pattern with ninject injection. My problem is my connections don't seem to get disposed. I have around 30 repositories (one for each table) and I get sql expiration timout preety quick. I can't use the regular using statement because the code recognize only the interface before the injection.
(in each controler I have my repositories interface instances which get injected via ninject).
I have searched the net but couldn't find a solution that was accurate for me.
can anyone please help me?
code example:
this is in the ninject controller under addBindings():
ninjectKernel.Bind<IMovieRepository>().To<MovieRepository>().InRequestScope();
and one of my repositories:
public class MovieRepository : IMovieRepository, IDisposable
{
private Entities dataContext = new Entities();
public System.Data.Entity.DbContext DbContext
{
get { return dataContext ?? (dataContext = new Entities()); }
}
public void Dispose() { dataContext.Dispose(); }
}
and in the Global.asax file:
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory() as IControllerFactory);
I would guess that your repositories (and therefore presumably your DbContexts) are being bound in transient scope, which I believe means a new one will be created every time Ninject needs to inject one somewhere. I'm not certain but I'm guessing then that these are all staying around for the lifetime of your application and maybe not being disposed.
Try binding your repositories in request scope, so that they are created and disposed per web request.
e.g.
Bind<IFooRepository>().To<ConcreteFooRepository>().InRequestScope();
From the Ninject wiki:
There are four built-in scopes available in Ninject:
Transient - A new instance of the type will be created each time one is requested. (This is the default scope). Binding method is .InTransientScope()
Singleton - Only a single instance of the type will be created, and the same instance will be returned for each subsequent request. Binding method is .InSingletonScope()
Thread - One instance of the type will be created per thread. Binding method is .InThreadScope()
Request - One instance of the type will be created per web request, and will be destroyed when the request ends. Binding method is .InRequestScope()
This kind of problem usually occur if long living objects depend on shorter living objects. E.g. A singleton service uses a repository in request scope.
I am new to WCF, I am using it to access MySql in silverlight application.
I have something simple like this:
[OperationContract]
public List GetPolitics()
{
return _registrationData.GetPolitics();
}
where RegistrationData is a .NET assembly that communicates with the MySql using MySqlConnection.
My question is, the WCF creates Async operations by default, is there a way to have a synchronous operation that blocks on the call while the DB is being fetched ? if so how ?
It's weird that according to your code, you have already used the synchronized operation. If you want to provide async operation, you need to provide a pair of method: BeginXXX, EndXXX. Please read this: Synchronous and Asynchronous Operations
And what do you mean by blocking the call? do you want to block the thread on server side?
I have a CakePHP 1.2 application that makes a number of AJAX calls using the AjaxHelper object. The AjaxHelper makes a call to a controller function which then returns some data back to the page.
I would like to log the SQL queries that are executed by the AJAX controller functions. Normally, I would just turn the debug level to 2 in config/core.php, however, this breaks my AJAX functionality because it causes the output SQL queries to be appended to the output that is returned to the client side.
To get around this issue, I would like to be able to log any SQL queries performed to a log file. Any suggestions?
I found a nice way of adding this logging functionality at this link:
http://cakephp.1045679.n5.nabble.com/Log-SQL-queries-td1281970.html
Basically, in your cake/libs/model/datasources/dbo/ directory, you can make a subclass of the dbo that you're using. For example, if you're using the dbo_mysql.php database driver, then you can make a new class file called dbo_mysql_with_log.php. The file would contain some code along the lines of the following:
App::import('Core', array('Model', 'datasource', 'dbosource', 'dbomysql'));
class DboMysqlWithLog extends DboMysql {
function _execute($sql) {
$this->log($sql);
return parent::_execute($sql);
}
}
In a nutshell, this class modifies (i.e. overrides) the _execute function of the superclass to log the SQL query before doing whatever logic it normally does.
You can modify your app/config/database.php configuration file to use the new driver that you just created.
This is a fantastic way to debug things like this, https://github.com/cakephp/debug_kit