asp.net / EntityFramework - Why does my application pool crashes? - c#

I'm trying to add a new method to my API.
The method's goal is to return a list of Partenaires having the given Prestation in their prestations.
When I'm calling the method by a GET request, the application pool of my API crashes. In the event logs, I have a warning called Microsoft-Windows-WAS and the linked error is:
A process serving application pool 'UphairApi2' suffered a fatal communication error with the Windows Process Activation Service. The process id was '3960'. The data field contains the error number.
And the network developer tool says that it failed to load response data.
Failed to load response data
When I'm returning return db.Partenaires.Where(p => p.PartenairePrestations.Any(pp => pp.Prestation.NomPrestation == prestation.Value)).ToString();, here's the returned request:
"SELECT\r\nExtent1.IdPartenaire, \r\nExtent1.FirstName, \r\nExtent1.LastName, \r\nExtent1.Email, \r\nExtent1.Password, \r\nExtent1.PasswordSalt, \r\nExtent1.Type, \r\nExtent1.Pays, \r\nExtent1.Ville, \r\nExtent1.CodePostale, \r\nExtent1.Adresse, \r\nExtent1.Lat, \r\nExtent1.Lng, \r\nExtent1.ImageUrl, \r\nExtent1.CouvertureUrl, \r\nExtent1.DateNaissance, \r\nExtent1.ADomicile, \r\nExtent1.SeDeplace, \r\nExtent1.DateAjout, \r\nExtent1.AdresseComplement, \r\nExtent1.TelMobile, \r\nExtent1.ValidationAutomatique, \r\nExtent1.NotifEmailMessage, \r\nExtent1.NotifEmailReservation, \r\nExtent1.NotifEmailPaiement, \r\nExtent1.NotifEmailNewsletter, \r\nExtent1.NotifSmsMessage, \r\nExtent1.NotifSmsReservation, \r\nExtent1.IdUserMango, \r\nExtent1.Iban, \r\nExtent1.TitulaireCompte, \r\nExtent1.IdWallet, \r\nExtent1.IdAccount, \r\nExtent1.Valide, \r\nExtent1.Son, \r\nExtent1.Push, \r\nExtent1.IdPhone\r\nFROM Partenaire AS Extent1\r\n WHERE EXISTS(SELECT\r\n1 AS C1\r\nFROM PartenairePrestation AS Extent2 INNER JOIN Prestation AS Extent3 ON Extent2.IdPrestation = Extent3.IdPrestation\r\n WHERE (Extent1.IdPartenaire = Extent2.IdPartenaire) AND ((Extent3.NomPrestation = #p__linq__0) OR ((Extent3.NomPrestation IS NULL) AND (#p__linq__0 IS NULL))))"
And the equivalent for Mysql Workbench:
SELECT Extent1.IdPartenaire, Extent1.FirstName, Extent1.LastName, Extent1.Email, Extent1.Password, Extent1.PasswordSalt, Extent1.Type, Extent1.Pays, Extent1.Ville, Extent1.CodePostale, Extent1.Adresse, Extent1.Lat, Extent1.Lng, Extent1.ImageUrl, Extent1.CouvertureUrl, Extent1.DateNaissance, Extent1.ADomicile, Extent1.SeDeplace, Extent1.DateAjout, Extent1.AdresseComplement, Extent1.TelMobile, Extent1.ValidationAutomatique, Extent1.NotifEmailMessage, Extent1.NotifEmailReservation, Extent1.NotifEmailPaiement, Extent1.NotifEmailNewsletter, Extent1.NotifSmsMessage, Extent1.NotifSmsReservation, Extent1.IdUserMango, Extent1.Iban, Extent1.TitulaireCompte, Extent1.IdWallet, Extent1.IdAccount, Extent1.Valide, Extent1.Son, Extent1.Push, Extent1.IdPhone FROM Partenaire AS Extent1 WHERE EXISTS(SELECT 1 AS C1 FROM PartenairePrestation AS Extent2 INNER JOIN Prestation AS Extent3 ON Extent2.IdPrestation = Extent3.IdPrestation WHERE (Extent1.IdPartenaire = Extent2.IdPartenaire) AND ((Extent3.NomPrestation = 'Barbe')))
I tested this request in MysqlWorkbench and a set of datas is well returned.
Here's my method:
// GET: api/Partenaires_prestations
[Authorize]
[Route("api/Partenaires_prestations")]
public List<PartenaireMapItem> GetPartenairesWithPrestations() {
Random rnd = new Random();
var queryString = Request.GetQueryNameValuePairs();
var prestation = queryString.FirstOrDefault();
return db.Partenaires.Where(p => p.PartenairePrestations.Any(pp => pp.Prestation.NomPrestation == prestation.Value))
.ToList()
.Select(p => new PartenaireMapItem {
IdPartenaire = p.IdPartenaire,
FirstName = p.FirstName,
LastName = p.LastName,
NomComplet = p.LastName.Substring(0,1).ToUpper() + ". " + p.FirstName,
Type = p.Type,
DureeMin = 50,
Lat = p.Lat,
Lng = p.Lng,
ImageUrl = p.ImageUrl,
SeDeplace = p.SeDeplace,
ADomicile = p.ADomicile,
Notes = p.NoteClientPartenaires,
Prestations = p.PartenairePrestations.Select(y => y.Prestation.NomPrestation).ToList();
}).ToList();
}
What am I doing wrong ?
Any help would be appreciated since I couldn't find another related thread on internet.

You will probably need to debug the API and specify more detail to help narrow down a cause. A couple of things I can see:
var prestation = queryString.FirstOrDefault();
// Handle when prestation comes back #null. Is that valid?
var results = db.Partenaires.Where(p => p.PartenairePrestations.Any(pp => pp.Prestation.NomPrestation == prestation.Value))
// .ToList() // Avoid .ToList() here... Select the entity properties you need.
.Select(p => new PartenaireMapItem {
IdPartenaire = p.IdPartenaire,
FirstName = p.FirstName,
LastName = p.LastName,
// NomComplet = p.LastName.Substring(0,1).ToUpper() + ". " + p.FirstName, // Remove. Make this a computed property in your view model.
Type = p.Type,
// DureeMin = 50, // Can remove, can be a computed property.
Lat = p.Lat,
Lng = p.Lng,
ImageUrl = p.ImageUrl,
SeDeplace = p.SeDeplace, // Ok if a String/value.
ADomicile = p.ADomicile, // Ok if a String/value.
Notes = p.NoteClientPartenaires, // Ok if a String/value.
Prestations = p.PartenairePrestations.Select(y => y.Prestation.NomPrestation).ToList(); // Assuming this is retrieving the names of presentations. List<string>.
}).ToList();
return results;
The early .ToList() was required because you were attempting to compute values (NameComplet) in the Linq expression that normally would have been fed to EF which your DB provider will not understand. For efficiency, only select mapped properties, and instead change any computed values to read-only properties on your view model. (PartenaireMapItem)
private string _nomComplet = null;
public string NomComplet
{
get { return _nomComplet ?? (_nomComplet = LastName.Substring(0,1).ToUpper() + ". " + FirstName); }
}
That example buffers the result assuming that the name details are read-only. If First/Last name can be updated, just return the calculated name each time.
The other properties should be fine, assuming that SeDeclace/ADomicile are string values and not child entities. The same goes for the list of Prestations. A list of strings for the Prestation names should be fine.
The other minor change I made was to retrieve the view models in a variable to inspect prior to returning. This better facilitates using a breakpoint to inspect the results before returning. From here determine if any error is coming back from the computation of the results, or something else such as serializing the resulting view models back to the client.

Related

Mongo DB with C# Driver sort after project

We are planning to move from MS SQL to Mongo DB, but we are hesitating because of the issue we are currently encountering.
Here's the code for the projection:
ProjectionDefinition<PrimaryCustomerIndividual, SearchResponse> projectionDefinition = Builders<PrimaryCustomerIndividual>.Projection.Expression(
a => new SearchResponse()
{
AdditionalContacts = "",
Adviser = a.Adviser,
ClientSince = a.ClientSince,
ClientNextActivityId = a.Activities.First().ActivityId,
CreateDate = a.CreateDateTime,
CustomerId = a.CustomerID,
Email = a.Email,
LastNote = a.Notes.First().Notes,
LeadOrigin = a.LeadOrigin,
LeadType = a.LeadType,
Mobile = a.Mobile,
Name = a.FirstName + " " + a.LastName,
NextReview = a.NextReview,
PhysicalAddress = a.PhysicalAddress,
UserNextActivityId = 0,
}
);
With the code above we are returning a different object from our collection object, Our collection object is PrimaryCustomerIndividual and we are returning SearchResponse we did this because there are fields that was needed to be populated by other collections. We have thousands of data and we are planning to have a pagination which will return 100 records per page but right now I'm having problem on how to accurately get the first 100 and then the second 100 if there's a sort.
and here is the code on how we are retrieving the data from the database:
var filter = Builders<PrimaryCustomerIndividual>.Filter.Where(a => a.IsActive);
var customers = customerCollection.Find(filter).Project(projectionDefinition).ToEnumerable()
I'm curios if there's a way to sort the data by the field of SearchResponse instead of fields of PrimaryCustomerIndiviual after the projection definition without converting it to list first?

How set OrderBy on GroupedEnumerable

My result set is not sorting. How do I set up OrderBy for type System.Linq.GroupedEnumerable
I've converted an application from Core 1.1 to 2.2. Everything ported over fine except one piece of logic that:
1) takes a response from a service call maps it to a GroupedEnumerable
2) takes the grouped set and passes it to a function that maps it to an object of type System.Linq.Enumerable.SelectEnumerableIterator.
The resulting object is properly populated but not sorted. I have tried the order by in the function parameter call and as a separate process afterwards.
//response = {myService.myClient.SearchNominationsResponse}
//groupedSet = {System.Linq.GroupedEnumerable<ServiceClients.myClient.NominationObject, long>}
//result = {System.Linq.Enumerable.SelectEnumerableIterator<System.Linq.IGrouping<long, ServiceClients.myClient.NominationObject>, app.ViewModels.EvaluationSummary>}
public IEnumerable<EvaluationSummary> GetEvaluationSummaries(string sortBy, string sortOrder, Filter filter = null)
{
var request = Mapper.MapSearchNominationRequest(filter);
request.IsDetailed = false;
var response = myService.SearchNominationsAsync(request).GetAwaiter().GetResult();
var groupedSet = response.mySet.GroupBy(n => n.SetId);
// I get a proper result but it is not sorted
var result = groupedSet.Select(
g => Mapper.MapEvaluationSummary(
g.OrderBy(g2 => sortBy + " " + sortOrder)
.Last()));
// Still not sorting
result = result.OrderBy(r => sortBy + sortOrder);
return result;
}
public EvaluationSummary MapEvaluationSummary(SetObject setIn)
{
var eval = new EvaluationSummary
{
setDate = setIn.Date,
setId = setIn.Id,
setTypeId = setIn.TypeId,
setTypeDescription = setIn.TypeDescription,
setStatusId = setIn.StatusId,
setStatusDescription = setIn.StatusDescription,
setBy = setIn.Manager,
setEmployee = setIn.employee
};
}
So in my view I have columns that list Date, Id, setEmployee. I can click on these values to issue a sort pattern and I can see that the sortBy and sortOrder variables are being passed in with proper values but the sorting is not happening.
I expect 'William' to appear before 'Bill' and then Bill to appear before 'William' when toggling the employee column header in my view.
Based off of the previous answers, I'm still not sure if I can substitute a property name in the LINQ with a variable. To fix my problem and move on I've implemented JS logic to sort my table headers. We had a custom JS that we use to format tables in our apps but it seems the sort functionality never worked. Anyway not an answer to my question but this is how I solved the problem:
Logic can be found at:
http://www.kryogenix.org/code/browser/sorttable/
-HaYen

Sitefinity: Dynamic Content query optimization with field values

I will attempt to be as specific as possible. So we are using Sitefinity 8.1.5800, I have a couple dynamic content modules named ReleaseNotes and ReleaseNoteItems. ReleaseNotes has some fields but no reference to ReleaseNoteItems.
Release Note Items has fields and a related data field to ReleaseNotes.
So I can query all ReleaseNoteItems as dynamic content pretty quickly less than a second.
I then use these objects provided by sitefinity and map them to a C# object so I can use strong type. This mapping process is taking almost a minute and using over 600 queries for only 322 items (N+1).
In Short: I need to get all sitefinity objects and Map them to a usable c# object quicker than I currently am.
The method for fetching the dynamic content items (takes milliseconds):
private IList<DynamicContent> GetAllLiveReleaseNoteItemsByReleaseNoteParentId(Guid releaseNoteParentId)
{
DynamicModuleManager dynamicModuleManager = DynamicModuleManager.GetManager(String.Empty);
Type releasenoteitemType = TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.ReleaseNoteItems.Releasenoteitem");
string releaseNoteParentTypeString = "Telerik.Sitefinity.DynamicTypes.Model.ReleaseNotes.Releasenote";
var provider = dynamicModuleManager.Provider as OpenAccessDynamicModuleProvider;
int? totalCount = 0;
var cultureName = "en";
Thread.CurrentThread.CurrentUICulture = new CultureInfo(cultureName);
Type releasenoteType = TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.ReleaseNotes.Releasenote");
// This is how we get the releasenote items through filtering
DynamicContent myCurrentItem = dynamicModuleManager.GetDataItem(releasenoteType, releaseNoteParentId);
var myMasterParent =
dynamicModuleManager.Lifecycle.GetMaster(myCurrentItem) as DynamicContent;
var relatingItems = provider.GetRelatedItems(
releaseNoteParentTypeString,
"OpenAccessProvider",
myMasterParent.Id,
string.Empty,
releasenoteitemType,
ContentLifecycleStatus.Live,
string.Empty,
string.Empty,
null,
null,
ref totalCount,
RelationDirection.Parent).OfType<DynamicContent>();
IList<DynamicContent> allReleaseNoteItems = relatingItems.ToList();
return allReleaseNoteItems;
}
This is the method that takes almost a minute that is mapping sitefinity object to C# object:
public IList<ReleaseNoteItemModel> GetReleaseNoteItemsByReleaseNoteParent(ReleaseNoteModel releaseNoteItemParent)
{
return GetAllLiveReleaseNoteItemsByReleaseNoteParentId(releaseNoteItemParent.Id).Select(rn => new ReleaseNoteItemModel
{
Id = rn.Id,
Added = rn.GetValue("Added") is bool ? (bool)rn.GetValue("Added") : false,
BugId = rn.GetValue<string>("bug_id"),
BugStatus = rn.GetValue<Lstring>("bugStatus"),
Category = rn.GetValue<Lstring>("category"),
Component = rn.GetValue<Lstring>("component"),
#Content = rn.GetValue<Lstring>("content"),
Criticality = rn.GetValue<Lstring>("criticality"),
Customer = rn.GetValue<string>("customer"),
Date = rn.GetValue<DateTime?>("date"),
Grouped = rn.GetValue<string>("grouped"),
Override = rn.GetValue<string>("override"),
Patch_Num = rn.GetValue<string>("patch_num"),
PublishedDate = rn.PublicationDate,
Risk = rn.GetValue<Lstring>("risk"),
Title = rn.GetValue<string>("Title"),
Summary = rn.GetValue<Lstring>("summary"),
Prod_Name = rn.GetValue<Lstring>("prod_name"),
ReleaseNoteParent = releaseNoteItemParent,
McProductId = GetMcProductId(rn.GetRelatedItems("McProducts").Cast<DynamicContent>()),
}).ToList();
}
Is there any way to optimize this all into one query or a better way of doing this? Taking almost a minute to map this objects is too long for what we need to do with them.
If there is no way we will have to cache the items or make a SQL query. I would rather not do caching or SQL query if I do not have to.
Thank you in advance for any and all help you can provide, I am new to posting questions on stackoverflow so if you need any additional data please let me know.
Is there a reason why you are doing a .ToList() for the items? Is it possible for you to avoid that. In my opinion, most of the time(of the 1 minute) is taken to convert all your items into a list. Conversion from Sitefinity object to C# object is not the culprit here.
Look Arno's answer here: https://plus.google.com/u/0/112295105425490148444/posts/QrsVtxj1sCB?cfem=1
You can use the "Content links manager" to query dynamic modules relationships (both by parent -ParentItemId- or by child -ChildItemId-) much faster:
var providerName = String.Empty;
var parentTitle = "Parent";
var relatedTitle = "RelatedItem3";
DynamicModuleManager dynamicModuleManager = DynamicModuleManager.GetManager(providerName);
Type parentType = TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.ParentModules.ParentModule");
Type relatedType = TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.RelatedModules.RelatedModule");
ContentLinksManager contentLinksManager = ContentLinksManager.GetManager();
// get the live version of all parent items
var parentItems = dynamicModuleManager.GetDataItems(parentType).Where(i => i.GetValue<string>("Title").Contains(parentTitle) && i.Status == ContentLifecycleStatus.Live && i.Visible);
// get the ids of the related items.
// We use the OriginalContentId property since we work with the live vesrions of the dynamic modules
var parentItemIds = parentItems.Select(i => i.OriginalContentId).ToList();
// get the live versions of all the schedules items
var relatedItems = dynamicModuleManager.GetDataItems(relatedType).Where(i => i.Status == ContentLifecycleStatus.Live && i.Visible && i.GetValue<string>("Title").Contains(relatedTitle));
// get the content links
var contentLinks = contentLinksManager.GetContentLinks().Where(cl => cl.ParentItemType == parentType.FullName && cl.ComponentPropertyName == "RelatedField" && parentItemIds.Contains(cl.ParentItemId) && cl.AvailableForLive);
// get the IDs of the desired parent items
var filteredParentItemIds = contentLinks.Join<ContentLink, DynamicContent, Guid, Guid>(relatedItems, (cl) => cl.ChildItemId, (i) => i.OriginalContentId, (cl, i) => cl.ParentItemId).Distinct();
// get the desired parent items by the filtered IDs
var filteredParentItems = parentItems.Where(i => filteredParentItemIds.Contains(i.OriginalContentId)).ToList();
I would imagine that every release note item under a single release note would be related to the same product wouldn't it?
If so, do you need to do the GetMcProductId method for every item?

Seeding data in Configuration.cs, creating duplicate data with AddOrUpdate

I am using Migrations in an MVC 4 EF5 application in Visual Studio 2012 Express with SQL Server 2012 Express, using Code First.
I use the Seed method in configuration.cs, firstly creating a Tags table. When I execute 'Update-Database -verbose -force' from Package Manager, it works correctly and doesn't create duplicate tags - and re-creates them if deleted:
db.Tags.AddOrUpdate(
t => t.Name,
new Tag { Name = "Bakery", NamePlural = "Bakeries" },
new Tag { Name = "Bar", NamePlural = "Bars" },
new Tag { Name = "Bookshop", NamePlural = "Bookshops" }
);
db.SaveChanges();
I then try and add related Places data:
db.Places.AddOrUpdate(
p => p.Name,
new Place
{
Name = "Shoreditch Grind",
URL = "shoreditch-grind-cafe",
Address = "213 Old St",
City = "London",
PostCode = "EC1V 9NR",
Website = "www.shoreditchgrind.com",
Phone = "020 7490 0101",
About = "Good coffee on the Silicon Roundabout",
Image = "noimage.png",
Tag = db.Tags.Single(t => t.Name == "Bar")
},
new Place
{
Name = "The Old Blue Last",
URL = "old-blue-last-pub",
Address = "38 Great Eastern St",
City = "London",
PostCode = "EC2A 3ES",
Website = "www.theoldbluelast.com",
Phone = "020 7739 7033",
About = "Pub of Vice Magazine",
Image = "noimage.png",
Tag = db.Tags.Single(t => t.Name == "Bakery")
}
);
This however creates duplicates, adding all the places again every time I execute 'Update-Database -verbose -force'
I'm new to MVC - and I also don't fully understand what this does:
p => p.Name,
I have a feeling perhaps I should be manually adding ID values to each object?
How can I run this without creating duplicate Places?
It would also be useful to be able to mark each Tag.Name as unique simply.
Thanks.
This may work:
var place = new Place
{
Name = "The Old Blue Last",
URL = "old-blue-last-pub",
Address = "38 Great Eastern St",
City = "London",
PostCode = "EC2A 3ES",
Website = "www.theoldbluelast.com",
Phone = "123 456 789", // updated number
About = "Pub of Vice Magazine",
Image = "noimage.png",
TagID = db.Tags.Single(t => t.Name == "Bakery").TagID
};
db.Places.AddOrUpdate(p => p.Name, place);
db.SaveChanges();
Since "The Old Blue Last" is already there, and we've updated based on p.Name, it should only update that entry changing Phone to "123 456 789". This similar to what you have tried, but may work. See more here.
You also mentioned that you are not sure what p => p.Name does. The => is called a Lambda Expression. It is an anonymous function. It is a method without a declaration, access modifier, return type, name etc. It's a short hand expression that allows you to write a method in the place you are going to use it.
See more here and here..

Errors when creating a custom Querable object with MVC and Subsonic pagedlist

hiya, i have the following code but when i try and create a new IQuerable i get an error that the interface cannot be implemented, if i take away the new i get a not implemented exception, have had to jump back and work on some old ASP classic sites for past month and for the life of me i can not wake my brain up into C# mode.
Could you please have a look at below and give me some clues on where i'm going wrong:
The code is to create a list of priceItems, but instead of a categoryID (int) i am going to be showing the name as string.
public ActionResult ViewPriceItems(int? page)
{
var crm = 0;
page = GetPage(page);
// try and create items2
IQueryable<ViewPriceItemsModel> items2 = new IQueryable<ViewPriceItemsModel>();
// the data to be paged,but unmodified
var olditems = PriceItem.All().OrderBy(x => x.PriceItemID);
foreach (var item in olditems)
{
// set category as the name not the ID for easier reading
items2.Concat(new [] {new ViewPriceItemsModel {ID = item.PriceItemID,
Name = item.PriceItem_Name,
Category = PriceCategory.SingleOrDefault(
x => x.PriceCategoryID == item.PriceItem_PriceCategory_ID).PriceCategory_Name,
Display = item.PriceItems_DisplayMethod}});
}
crm = olditems.Count() / MaxResultsPerPage;
ViewData["numtpages"] = crm;
ViewData["curtpage"] = page + 1;
// return a paged result set
return View(new PagedList<ViewPriceItemsModel>(items2, page ?? 0, MaxResultsPerPage));
}
many thanks
you do not need to create items2. remove the line with comment try and create items2. Use the following code. I have not tested this. But I hope this works.
var items2 = (from item in olditems
select new ViewPriceItemsModel
{
ID = item.PriceItemID,
Name = item.PriceItem_Name,
Category = PriceCategory.SingleOrDefault(
x => x.PriceCategoryID == item.PriceItem_PriceCategory_ID).PriceCategory_Name,
Display = item.PriceItems_DisplayMethod
}).AsQueryable();

Categories