How to defer query execution in NHibernate QueryOver - c#-4.0

I am trying to execute 3 queries but want to execuate all at one database call. I gone through https://ayende.com/blog/3979/nhibernate-futures but it still executes each query individually. I am using QueryOver instead of CreateCriteria.
Can anyone help how to achieve this?
my query is like
var changedScriptsInHeader = _session.QueryOver<ProgramHeader>()
.Where(x => x.ModifiedTime.IsBetween(changedFrom).And(changedTo))
.Select(x => x.ScriptNumber)
.Future<string>();
var changedScriptsInDetail = _session.QueryOver<ProgramDetail>()
.Where(x => x.UpdatedDate.IsBetween(changedFrom).And(changedTo))
.SelectList(list => list.SelectGroup(pr => pr.ScriptNumber))
.Future<string>();
var changedScriptsInReplay = _session.QueryOver<ProgramReplay>()
.Where(x => x.UpdatedDate.IsBetween(changedFrom).And(changedTo))
.SelectList(list => list.SelectGroup(pr => pr.ScriptNumber))
.Future<string>();
Thanks

Related

Autofac/Automapper - Custom value resolvers Error

Autofac Registration:
builder.RegisterType<RelatedTransportMangerResolver>().AsSelf();
builder.Register(context => new MapperConfiguration(cfg =>
{
cfg.AddProfile<AssetMapperProfile>();
})).AsSelf().SingleInstance();
builder.Register(c => c.Resolve<MapperConfiguration>().CreateMapper(c.Resolve))
.As<IMapper>()
.InstancePerLifetimeScope();
Map that uses the custom value resolver:
CreateMap<TrafficArea, TrafficAreaViewModel>()
.ForMember(ta => ta.TransportManagers,
opt => opt.MapFrom(ta =>
ta.TrafficAreaKeyContacts
.Where(kc => kc.KeyContactGroup.HasFlag(KeyContactGroup.TransportManager))
.Select(atr => atr.KeyContact)))
.ForMember(ta => ta.RelatedTransportManagers,
opt => opt.MapFrom<RelatedTransportMangerResolver>());
Error being returned is:
This resolve operation has already ended. When registering components using lambdas, the IComponentContext 'c' parameter to the lambda cannot be stored. Instead, either resolve IComponentContext again from 'c', or resolve a Func<> based factory to create subsequent components from.
Any ideas on how to fix this error?
Should of done a bit more digging myself first...
Fix here if anybody has this same issue:
builder.Register(c =>
{
//This resolves a new context that can be used later.
var context = c.Resolve<IComponentContext>();
var config = context.Resolve<MapperConfiguration>();
return config.CreateMapper(context.Resolve);
})
.As<IMapper>()
.InstancePerLifetimeScope();

Firestore cloud function asynchronous execution with promise

I have orders collection and products collection in my application. The user can have multiple products in their single order. What I want to do is calculating the amount of each product reading through products collection and then perform the further action. Below is what I got as of now.
exports.myfunc = functions.firestore.document('collection/{collid}')
.onCreate(event => {
let data = event.data.data();
const products = data.products;
const prices = [];
_.each(products, (data1, index) => {
const weight = data1.weight;
const isLess = data1.isLess;
firebaseAdmin.firestore().collection('collection').doc(data1.productId).onSnapshot(data2 => {
let amount = weight === '1/2' ? data2.data().price1 : data2.data().price1 * weight;
amount += isLess ? 50 : 0;
prices.push(amount);
});
});
//Do some task after _.each with new total
});
But am not able to achieve synchronous task here, so that I can store actual amount for the product against its order and calculate total to store in document.
Could anyone please tell me how I achieve the above-said scenarios? How I can work along with promise and then callback?
You can map the products array to promises, like this:
var productPromises = products.map(product => {
return new Promise((resolve, reject) => {
firebaseOperation()...onSnapshot(resolve)
})
})
Promise.all(productPromises).then(results => {
// process all results at once
})
First, don't use onSnapshot() with Cloud Functions. That attaches a listener that stay listening indefinitely, until you remove it. That's not what you want at all, because functions can't execute indefinitely.
Instead, use get(), which returns a promise when the fetch is complete.
Also, you could consider accumulating all the documents you want to access into an array and use getAll() (with the spread operator on the array) to fetch them all.

RxJs Basing a Filter on Another Observable

I have a list of words with pronunciation data in a text file. What I would like to do is have the user enter a word, and then have the program check to see if I have data on that word in that file. I'd like to do it in RxJs, which I am new to.
The code below is the closest I can get to what I want. Within my main stream I have a filter call that creates a dependent stream, called 'checkstream'. What I don't understand is how to use the results of that dependent stream in the filter method of my main stream. Currently that filter method fails, but I still get the data to the screen by console logging it.
If there is data in my text file for a word, then the checkstream will end up being an observable containing just the data I want to retrieve and show to the user. I want to somehow pipe that data down to the consumer of my main stream, but I don't understand how to do that.
I would appreciate any help you can provide. Even just some intuition would be useful.
var Rx = require('rx');
var RxNode = require('rx-node');
var fs = require('fs');
var split = require('split');
RxNode.fromReadableStream(process.stdin)
.map( (inputData) => {
var inputWord = inputData.toString().trim();
return inputWord;
})
.map( (inputWord) => {
var checkStream = fs.createReadStream('./dict.txt');
RxNode.fromReadableStream(checkStream.pipe(split()))
.map( (lineFromFile) => {
return JSON.parse(lineFromFile);
})
.filter((parsedDataToCheck) => {
return parsedDataToCheck.word.toLowerCase().trim() === inputWord; })
.subscribe((dataThatMatches) => { console.log(dataThatMatches) });
return dataToReturn;
})
.subscribe(function(dataToReturn) {
console.log(dataToReturn);
});
Maybe something like this:
var Rx = require('rx');
var RxNode = require('rx-node');
var fs = require('fs');
var split = require('split');
RxNode.fromReadableStream(process.stdin).map(
inputData => inputData.toString().trim()
).flatMap(inputWord => {
var checkStream = fs.createReadStream('./dict.txt');
return RxNode.fromReadableStream(
checkStream.pipe(split())
).map(
lineFromFile => JSON.parse(lineFromFile)
).find(
parsedDataToCheck => parsedDataToCheck.word.toLowerCase().trim() === inputWord
);
}).subscribe(dataToReturn => {
console.log(dataToReturn);
});
Note that it is possible that the input words from stdin get reordered after filtering due to the asynchronous fs reads.

Entity Framework 4.3 and Threading

I am getting the error below when running a query in Entity Framework 4.3 in a thread.
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
Below is where my thread starts and it errors at var item = _gamesRepository.Get(gameIncludes, q => q.Id == gameId);. Am I doing something wrong or should I use a different approach?
public void ProcessGame(int gameId)
{
new Thread(() =>
{
Expression<Func<Game, object>>[] gameIncludes = {
q => q.DivisionGameTeamResults,
q => q.DivisionGameTeamResults.Select(g => g.DivisionBracketGameParticipant),
q => q.DivisionGameTeamResults.Select(g => g.DivisionTeamPoolGame),
q => q.DivisionGameTeamResults.Select(g => g.DivisionTeamPoolGame.DivisionTeamPool),
e => e.DivisionGameTeamResults.Select(q => q.DivisionBracketGameParticipant.DivisionBracketGame.DivisionBracketGameParticipants.Select(t => t.DivisionBracketGameParticipantTeam.DivisionTeam.Team)),
e => e.DivisionGameTeamResults.Select(q => q.DivisionBracketGameParticipant.DivisionBracketGame.DivisionLoserBracketGameParticipants.Select(d => d.DivisionBracketGameParticipantPool.DivisionPool)),
e => e.DivisionGameTeamResults.Select(q => q.DivisionBracketGameParticipant.DivisionBracketGame.DivisionLoserBracketGameParticipants.Select(d => d.DivisionBracketGameParticipantTeamPool.DivisionTeamPool.DivisionTeam)),
q => q.DivisionGameTeamResults.Select(d => d.DivisionTeamPoolGame.DivisionTeamPool.DivisionPool.Division.Event.Members),
q => q.DivisionGameTeamResults.Select(d => d.DivisionBracketGameParticipant.DivisionBracketGame.BracketPart.DivisionBracketPart.DivisionBracket.Division.Event.Members)
};
var item = _gamesRepository.Get(gameIncludes, q => q.Id == gameId);
if (item != null)
{
if (item.DivisionGameTeamResults.All(d => d.DivisionTeamPoolGame != null))
{
// Pool Game
_divisionBracketsService.ProcessPoolGame(item);
}
else if (item.DivisionGameTeamResults.All(d => d.DivisionBracketGameParticipant != null))
{
// Bracket Game
_divisionBracketsService.ProcessBracketGame(item);
}
UnitOfWork.Commit();
}
}).Start();
}
UPDATE:
I made the required changes to fix that issue.
var gamesRepository = DependencyResolver.Current.GetService<IGamesRepository>();
var divisionBracketsService = DependencyResolver.Current.GetService<IDivisionBracketsService>();
Repository and unit of work should be owned by your thread for two reasons:
EF is not thread safe - sharing context among threads can lead you to false belief that you can do concurrent operations on the same context instance but you in general can't. This may change in EF6 where async support will be implemented but current version is only for single threaded processing.
If you share context between threads you must ensure that the thread owning the context does not dispose the context before any other thread dependent on that context finishes its processing - that is your current problem. It means that your calling thread should wait on your processing thread to complete.

Multi-Threaded SubQueries using Entity Framework throws errors

I have been trying to update the performance of my code in regards to database queries. The problem I am currently running into is that I cant seem to find a way to get a new context for each subQuery.
Using the below simplified code will inconsitantly generate a "The underlying provider failed on Open."
using (var context = getNewContextObject())
{
var result = new SomeResultObject();
var parentQuery = context.SomeTable.Where(x => x.Name = "asdf");
Parallel.Invoke(() =>
{
result.count1 = parentQuery.Where(x => x.Amount >= 100 & x.Amount < 2000).Count();
}, () =>
{
result.count2 = parentQuery.Where(x => x.Amount < 100).Count();
}
, () =>
{
result.count3 = parentQuery.Where(x => x.Amount >= 2000).Count();
}
);
}
The only way around this so far seems to be to rebuild the entire query for each subQuery with a new context. Is there any way to avoid building each query from the bottom up with a new Context? Can I instead just attach each subquery query to a new context? I am looking for something like the below.
Parallel.Invoke(() =>
{
var subQuery = parentQuery.Where(x => x.Amount >= 100 & x.Amount < 2000).Count();
subQuery.Context = getNewContextObject();
result.count1 = subQuery.Count();
}, () =>
{
var subQuery = parentQuery.Where(x => x.Amount < 100).Count();
subQuery.Context = getNewContextObject();
result.count2 = subQuery.Count();
}
, () =>
{
var subQuery = parentQuery.Where(x => x.Amount >= 2000).Count();
subQuery.Context = getNewContextObject();
result.count3 = subQuery.Count();
}
);
}
I'm not sure how this exactly relates to your problem but none of EF features are thread safe so I expect that running multiple queries on the same context instance in parallel can blow up for any reason. For example they access the same connection property in the context but threads don't know about each other so they can close the connection to other thread or replace the instance with other connection instance (you can try to open the connection manually before you run parallel threads and close it once all threads are done but it doesn't have to be the only problem).

Resources