I have a local and development environment, each very similar to each other (OS differences aside). They both run the same project which is making use of the Entity Framework. I use LINQpad quite a bit to interrogate data on both environments -- but where required I have access to SQL etc. etc.
So, this is all started with a very strange occurance. Within my business logic layer, I make a call to get a list of Contacts and then marshall that list into a custom type. The custom-type calls for an Initial index based on the name of each of the contacts.
For reference, this is the code that performs the marshalling:-
private static IEnumerable<AlphabetisedContact> _getGroupedContacts(int clientid)
{
return _getLiteContacts(clientid).GroupBy(c => c.Name[0]).Select(
g => new AlphabetisedContact { Initial = g.Key, Contacts = g.ToList() }).OrderBy(g => g.Initial);
}
So, this all seems to work fine. Except, it never returns any Contact with the first initial of a. I decided to try and debug this and using LINQpad found a weirdness. Whether this has anything to do with my code not returning a contacts I don't know (??), but this was the weirdness I found:-
Local Machine:-
Development Machine:-
For the less eagle-eyed of you, the Entity Set Name returned by EF, seems to be different. With the development machine, they're returned with underscores between words -- which is not how the EDMX was setup. For example, it is Name on local, Contact_name on dev. Again, this may have absolutely nothing to do with why I can't get a contacts. I don't get errors on the dev box, contacts are returned etc. etc. but I can't get a contacts.
Can anyone offer some assistance/advice/guidance on how to fix this? It's become a case of "wood-for-the-trees" now...
Help appreciated.
Turns out this was a catastrophic boo-boo on my part. Please see answer to this on this SO:
Why Won't This LINQ Return A Particular Initial?
Thanks to all who took the time to take a peek - and at least a stab at answer.
;)
Related
Good evening!
I am currently working on the backend of my application and I need to get a list of all properties of a certain datatype but only the ones in the current page.
listFiltersCms = _umbraco.ContentAtRoot().SelectMany(c => c.Descendants<DataFilters>()).ToList();
This line above gathers all the filters from all the pages, but I want the filters from a specific page (can be currentPage).
I have tried something like this:
var listFiltersCms = _umbraco.AssignedContentItem.SelectMany(c => c.Descendants<DataFilter>()).ToList();
But without any luck :( Any ideas?
Not entirely sure what you mean by "the backend of my application" - are you inside Umbraco or on a public website?
I ask because there is a fairly straightforward way of getting all info on a specific datatype, but it is not really meant to be used on public facing websites. It can be, but it might be taxing on the system as I believe it queries the database directly, which is not ideal.
Anyway, you might want to take a look at the DataTypeService:
https://our.umbraco.com/Documentation/Reference/Management/Services/DataTypeService/Index-v8
And here you can see what options you have for using it (not very explanatory, but I spot a few methods you could probably look into):
https://our.umbraco.com/apidocs/v8/csharp/api/Umbraco.Core.Services.IDataTypeService.html
If you decide to use the service in a scenario where there will be a lot of requests, maybe consider caching the output to spare the database.
The way I solved this issue was by getting the page in the correct model. In my case all I had to do was:
(_umbraco.AssignedContentItem as PageModel).FilterCustomMeasures;
I looked at other similar questions, but I cannot figure this out on my own. I am currently using Lightswitch 12.0.3 Update 4 version of Lightswitch and I previous versions of Lightswitch I could do these kind of things with ease... So I don't understand what changed and why I am not able to do this anymore.
I get an error:
Property or indexer 'LightSwitchApplication.Report.Customer' cannot be assigned to -- it is read only
Where Report is my screen and Customer is my table. So in the code behind (of the screen) I am trying to do this:
partial void Report_InitializeDataWorkspace(List<IDataService> saveChangesTo)
{
if (this.CustomerId.HasValue)
{
this.Customer = this.DataWorkspace.ApplicationData.Customers.Where(w => w.Id == this.CustomerId.Value).Single();
}
}
And in this case, CustomerId is a local int property added to my screen.
Now the error is that this.Customer cannot be assigned to, because it is read-only.
What am I missing?
Also, I am getting the same error in another place:
Property or indexer 'LightSwitchApplication.Report.NewProduct' cannot be assigned to -- it is read only
partial void CreateNewProduct_Execute()
{
this.NewProduct = this.DataWorkspace.ApplicationData.Products.AddNew();
this.OpenModalWindow("NewProduct");
}
I suspect the issues you're encountering relate to the many changes between the early 2011 beta versions and the RTM release.
Whilst I'm a little bit rusty on the Silverlight side of things (having focused on the HTML 5 LightSwitch route in recent years) I'll try and provide some pointers which may help.
As regards your Report_InitializeDataWorkspace code (which I'm guessing is intended to default the this.Customer values based upon a passed parameter) you should be able to tackle this as follows: -
if (this.CustomerId.HasValue)
{
var c = this.DataWorkspace.ApplicationData.Customers.Where(w => w.Id == this.CustomerId.Value).Single();
this.Customer.Name = c.Name;
this.Customer.AddressLine1 = c.AddressLine1;
}
If this isn't your intention, please can you provide a little more background regarding what you're trying to implement.
Regarding the CreateNewProduct code you should be able to implement something along the following lines: -
partial void CreateNewProduct_Execute()
{
Product newProduct = this.DataWorkspace.ApplicationData.Products.AddNew();
this.Products.SelectedItem = newProduct;
this.OpenModalWindow("NewProduct");
}
Again, if I've misunderstood your intentions, please can you provide more background.
The following article may also help with this area (though it only covers the vb approach and not c# code): -
LightSwitch Team Blog - Creating a Custom Add or Edit Dialog (Sheel Shah)
Whilst the article is circa the 2011 edition, it should still be reasonably relevant to the 2013 update 4 version you're using.
without seeing the declaration of 'Customer' and 'NewProduct', I can only guess that you may have declared it as a Property with a Getter only - no Setter.
If this is not the case, could you show more code that demonstrates what is failing.
I solved the "problem" - It was my fault and failure to understand the difference between a data item as Query of type Customer and data item as Local Property of type Customer.
So in other words, I added both Customer and Product as local screen members instead of queries and now my code works as intended.
So we have a WCF Data Service exposing OData with an Entity Framework (v5.6) model.
Since we wanted to filter the data based on authentication and access control, some Query Interceptors were added. At first, all they had to do was get the user's scope and match that to an entity's property - something like this:
[QueryInterceptor("Entity")]
public Expression<Func<Entity, bool>> EntitiesInterceptor()
{
// Get user scope
string userScope = GetUserScope();
return entity => entity.Scope.StartsWith(userScope));
}
This worked as expected, and everything was well with the world.
Later on, we wanted to evolve the interceptor to allow matching with a list of scopes. So we changed the code to something like this:
// Get user scopes
string[] validScopes = GetUserScopes();
return entity => validUnits.Any(scope => entity.Scope.StartsWith(scope));
This seemed to work as long as our OData requests didn't expand beyond one level of relations. So, for instance, stuff like:
/ODataService.svc/Entity?$expand=OtherEntity
/ODataService.svc/Entity?$expand=OtherEntity,AnotherEntity
...would process just fine. However, when we start querying deeper relations:
/ODataService.svc/Entity?$expand=OtherEntity/YetAnotherEntity
We start getting an 'Object reference not set to an instance of an Object' error from System.Entity.Data. The stack trace is really long and mentions lots of classes on the System.Data namespace. Sadly, it does not mention any line in our code.
Link to full stack trace
It seems to us that the problem is on how EF is converting our lambda expressions to queries. We've tried replacing the .Any() with other equivalents like .Count(expression) > 0 in hopes that the conversion would work, but alas, the result was the same.
So, can anyone think of a different way to approach the problem? Has somebody faced the same issue? Or is it something that we're doing wrong?
Thanks in advance for reading the huge wall of text above.
Consider this code:
var svc = new ProductDesignerEntities(AppSettings.ProductDesignerServiceLocation);
var scenariox = svc.Scenarios
.Where(o => o.ID == id)
.FirstOrDefault();
var scenario = svc.Scenarios
.Expand(o => o.SomeNavigationProperty)
.Where(o => o.ID == id)
.FirstOrDefault();
When this code runs, scenario.SomeNavigationProperty will be unpopulated. Commenting out the code which populates scenariox fixes it. Why is this? Is it possible to fix this through configuration of the service context or the data service, or will I have to change the design of my code in some fashion?
The alternatives that I can think of are all inferior in some capacity:
Create a ProductDesignerEntities instance per action. This kills within-request caching almost entirely.
Create a ProductDesignerEntities instance per controller. Less annoying with a base controller class, but this kills caching between controllers, and wouldn't fix the issue if different actions in the same controller needed different sets of navigation properties from the same table.
Manually populate the property if it is empty. Difficult to consistently implement a manual solution like this; bound to be a source of bugs.
Always manually populate the property. Kind of defeats the purpose of navigation properties.
Ensure that all uses of the table within a request have the same .Expand() list. Extremely annoying and begging for hard-to-fix bugs.
I'm starting to lean toward the first alternative. It seems to have the least issues, despite the additional overhead of a new connection for each instance :/
EDIT: I managed to get the service queries to run through Fiddler, and they look correct. But the navigation property on scenario still winds up empty unless I comment out the scenariox code.
After doing further research, it appears that you're supposed to create a new ProductDesignerEntities instance within each use context anyway, so that's the solution I'll be going with. It bugs me a lot that I wasn't able to properly fix the problem, though!
I'm going to write it off as either a very weird configuration issue, or a bug in WCF data services, because according to Fiddler, it does actually perform the request for the additional data; it just doesn't show up in the returned object.
I've been researching to find out how and what to use to get say the name's of the fields in a class, then to invoke that class and get the properties of the class, as in the field values.
Give you an example, Say if I one to get one value from one record from one table, I would create an object of that class as in;
DBTable<cars> cartable = new DBTable<cars>(1) //passing 1 is a dataset number
cartable.GetLastRec(); OR cartable.Attributes.Key.carIdx // record index
cartable.GetKeyRec();
// Now I print the value
Console.WriteLine("Car number: " + cartable.Attributes.Data.number;
It's easy to get one record, it's like an Object Orientated Database but not sure if it isn't, I don't have any knowledge of the database system, just that the classes are used to talk to a DLL file and pass some numbers.
so far I've been testing with collections, inheriting, ORM, and nothing seams to be able to describe the very simple process going on, Even dynamic invoking objects and iterating over it's attributes
What I hope do is;
Datagridview => Table Classes => DLL entry points => Database
If anyone has had the same challenge or maybe I have the wrong approach here, but completely lost at this stage, Any Idea's welcome
Thanks in Advance
btw: I'm using VS2005, .NET 2.0
The only way to do this is by providing your own PropertyDescriptorCollection.
A search here or on Google, should point you in the correct direction.