This will probably be a basic questions for the LINQ & architecture experts however I am failing to understand a problem i've encounted when trying to update a 'Static ObservableCollection.
Me.Grid1.ItemsSource = ContactList
Me.Grid2.ItemsSource = From s In ContactList Where s.ContactTypes.Any(Function(t) t.ContactTypeName = "Christmas List")
If I add a new Contact with the ContactType "Christmas List" to the ContactList ObservableCollection, Grid1 reflects the additional Contact however Grid2 does not reflect the change unless I rebind.
Anyway to Reflect the change in Grid2 to show the new Contact with the queried ContactType
Grid2 is actually binding to an IEnumerable(Of Contact) instead of an Observable Collection. That's why the change isn't reflected in Grid2. You need to cause your Linq query to reexecute using an event or INotifyPropertyChanged.
It could be happening due to the deferred execution nature of LINQ query. The values are fetched only when, you start enumerating over the result set. That is why, you have to rebind the data source, to see the change. Try adding ToList(), method at the end of the query. For e.g.
Me.Grid2.ItemsSource = From s In ContactList Where s.ContactTypes.Any(Function(t) t.ContactTypeName = "Christmas List").ToList();
You need my ObservableComputations library. Using this library you can code like this:
Me.Grid2.ItemsSource = ContactList.Filtering(c => c.ContactTypes.ContainsComputing("Christmas List").Value);
Filtering extention method returns instance of ObservableCollection and reflects all the changes in the ContactList collection and ContactTypes collection. Writing the code above, I assumed contactContactTypes id ObservableCollection. If this is not so, then you can code:
Me.Grid2.ItemsSource = ContactList.Filtering(c => c.ContactTypes.Contains("Christmas List"));
In this case do not forget to add the implementation of the INotifyPropertyChanged interface to Contact class, so that the result ObservableCollection reflects the change of contact.ContactTypes property.
Related
I have a document in RavenDB that looks looks like:
{
"ItemId": 1,
"Title": "Villa
}
With the following metadata:
Raven-Clr-Type: MyNamespace.Item, MyNamespace
Raven-Entity-Name: Doelkaarten
So I serialized with a type MyNamespace.Item, but gave it my own Raven-Entity-Name, so it get its own collection.
In my code I define an index:
public class DoelkaartenIndex : AbstractIndexCreationTask<Item>
{
public DoelkaartenIndex()
{
// MetadataFor(doc)["Raven-Entity-Name"].ToString() == "Doelkaarten"
Map = items => from item in items
where MetadataFor(item)["Raven-Entity-Name"].ToString() == "Doelkaarten"
select new {Id = item.ItemId, Name = item.Title};
}
}
In the Index it is translated in the "Maps" field to:
docs.Items
.Where(item => item["#metadata"]["Raven-Entity-Name"].ToString() == "Doelkaarten")
.Select(item => new {Id = item.ItemId, Name = item.Title})
A query on the index never gives results.
If the Maps field is manually changed to the code below it works...
from doc in docs
where doc["#metadata"]["Raven-Entity-Name"] == "Doelkaarten"
select new { Id = doc.ItemId, Name=doc.Title };
How is it possible to define in code the index that gives the required result?
RavenDB used: RavenHQ, Build #961
UPDATE:
What I'm doing is the following: I want to use SharePoint as a CMS, and use RavenDB as a ready-only replication of the SharePoint list data. I created a tool to sync from SharePoint lists to RavenDB. I have a generic type Item that I create from a SharePoint list item and that I serialize into RavenDB. So all my docs are of type Item. But they come from different lists with different properties, so I want to be able to differentiate. You propose to differentiate on an additional property, this would perfectly work. But then I will see all list items from all lists in one big Items collection... What would you think to be the best approach to this problem? Or just live with it? I want to use the indexes to create projections from all data in an Item to the actual data that I need.
You can't easily change the name of a collection this way. The server-side will use the Raven-Entity-Name metadata, but the client side will determine the collection name via the conventions registered with the document store. The default convention being to use the type name of the entity.
You can provide your own custom convention by assigning a new function to DocumentStore.Conventions.FindTypeTagName - but it would probably be cumbersome to do that for every entity. You could create a custom attribute to apply to your entities and then write the function to look for and understand that attribute.
Really the simplest way is just to call your entity Doelkaarten instead of Item.
Regarding why the change in indexing works - it's not because of the switch in linq syntax. It's because you said from doc in docs instead of from doc in docs.Items. You probably could have done from doc in docs.Doelkaartens instead of using the where clause. They are equivalent. See this page in the docs for further examples.
I am wondering if it is possible to map a named native query on the fly instead of getting back a list of Object[] and then looping through and setting up the object that way. I have a call which I know ill return a massive data set and I want to be able to map it right to my entity. Can I do that or will I have to continue looping through the result set.
Here is what I am doing now...
List<Provider> ObjList = (List<Provider>) emf.createNativeQuery(assembleQuery(organizationIDs, 5)).getResultList();
That is my entity, the List (my entity is the provider). Normally I would just return a List<Object[]>
and then I would loop through that to get back all the objects and set them up as new providers and add them to a list....
//List<Provider> provList = new ArrayList<Provider>();
/*for(Object[] obj: ObjList)
{
provList.add(this.GetProviderFromObj(obj));
}*/
As you can see I commented that section of the code out to try this out. I know you can map named native queries if you put your native query in the entity itself and then call it via createNamedQuery. I would do it that way, but I need to use the IN oracle keyword because I have a list of ID's that I want to check against. It is not just one that is needed. And as we all know, native queruies don't handle the in keyword to well. Any advice?
Sigh, If only the IN keyword was supported well for NamedNativeQueries.
Assuming that Provider is configured as a JPA entity, you should be able to specify the class as the second parameter to your createNativeQuery call. For example:
List<Provider> ObjList = (List<Provider>) emf.createNativeQuery(assembleQuery(organizationIDs, 5), Provider.class).getResultList();
According to the documentation, "At a minimum, your SQL must select the class' primary key columns, discriminator column (if mapped), and version column (also if mapped)."
See the OpenJPA documentation for more details.
I am performing validation based on attributes in metadata.cs file. I am using Entity framework 4.0 and using wcf ria services. I want to know what is the equivalent of Page.IsValid in asp.net in silverlight? How do i ensure that the entity is in correct state before saving it? If i do not ensure this an exception fires which looks very ugly. I found a property named entityName.ValidationErrorCount so if my entity is named User i do objUser.ValidationErrorCount is less than equal to 0 i save it. Problem with this approach is if the user doesn't enter value in any of the textbox then subsequently all the values in the entity are null. So ValidationErrorCount property returns 0 because all are null values and thus my program tries to save the entity but naturally the entity is in incorrect state so exception fires. How do i get past this problem?
I hope i am clear. If not, please let me know. Thanks in advance :)
You can validate an entity using the Validator class (from the System.ComponentModel.DataAnnotations
namespace), like so (where entity is a reference to the entity to be validated):
List<ValidationResult> validationResults = new List<ValidationResult>();
ValidationContext validationContext = new ValidationContext(entity, null, null);
bool isValid = Validator.TryValidateObject(entity, validationContext, validationResults, true);
Alternatively, are you using the DataForm control? If so, there's an even easier way to check whether the current item is valid, by calling the ValidateItem() method on the DataForm. This will return a boolean indicating whether the current item is valid (you can also check the IsItemValid property of the DataForm). It will also update the bound controls to show their validation status. If you're not using the DataForm, then it will certainly make it easier if you can. Otherwise, simply add the validation results to the entity's ValidationErrors property:
foreach (ValidationResult result in validationResults)
entity.ValidationErrors.Add(result);
Hope this helps...
Chris
I'd like to add a label to a wicket panel where the label's model is an enum value. Based on the value of that enum, I'd like to display a different message pulled from the page's properties file.
For example, here's an enum:
public enum ApprovalType { UNAPPROVED, APPROVED, BLOCKED };
I can easily add a label to the panel that has this enum as its model:
add(new Label("approval", new Model(ApprovalType.APPROVED)));
However, this will simply output UNAPPROVED, APPROVED, or BLOCKED. I'd like to output a localized message that is selected based on the value of this enum.
So if I have this properties file, what's the best way to get these messages to output?
UNAPPROVED=Your membership is currently pending approval
APPROVED=Your membership has been approved
BLOCKED=You have been blocked from membership
I can get it working like this:
add(new Label("approval", new ResourceModel(ApprovalType.APPROVED.name());
But the problem is that ResourceModel only accepts a string (resource key). I'd like to pull the value of the resource key automatically from a model (preferrably a CompoundPropertyModel). In other words, I don't want to do this:
Member member = (Member) getDefaultModelObject();
add(new Label("approval", new ResourceModel(member.getApproval().name())));
I'd rather do something like:
add(new EnumLabel("approval"); // assuming I have a CompoundPropertyModel
Is there a component that does this that comes with Wicket? Or do I need to write my own?
Lastly, I discovered this also works:
add(new Label("approval", new StringResourceModel(
"${}",
new PropertyModel<ApprovalType>(getDefaultModel(),"approval")
)));
But this seems overly verbose, and still doesn't utilize the simplicity of using CompoundPropertyModel.
Ideas?
Not sure if this 'll work, but maybe you could try writing your own EnumModel class that takes the value of an Enum and returns a ResourceModel value..
Please say so if the above isn't clear enough, I'll try to elaborate.
NHibernate allows me to query a database and get an IList of objects in return. Suppose I get a list of a couple of dozen objects and modify a half-dozen or so. Does NHibernate have a way to persist changes to the collection, or do I have to persist each object as I change it?
Here's an example. Suppose I run the following code:
var hql = "from Project";
var query = session.CreateQuery(hql);
var myProjectList = query.List<Project>();
I will get back an IList that contains all projects. Now suppose I execute the following code:
var myNewProject = new Project("My New Project");
myProjectList .Add(myNewProject);
And let's say I do this several times, adding several new projects to the list. Now I'm ready to persist the changes to the collection.
I'd like to persist the changes by simply passing myProjectList to the current ISession for updating. But ISession.SaveOrUpdate() appears to take only individual objects, not collections like myProjectList. Is there a way that I can persist changes to myProjectList, or do I have to persist each new object as I create it? Thanks for your help.
David Veeneman
Foresight Systems
If you load objects like in your example - then yes you have to persist them one by one.
However, if you make a small design change, and load something like : Account that has an IList<Project> - if you specify cascade "what_cascade_you_need" in the mapping , then when you change the projects on Account , you only have to save Account and everything will get saved.