I have a baseclass in my website with a property: CurrentUser.
The get method of this property will create a new context and get a User object from the database based on auth cookie information. So far so good.
But since the context is closed, all I can do outside this, is to call properties directly under User, for example FirstName.
But as soon as I try to get a relation for example, like CurrentUser.UserOffices this won't work since I didn't include UserOffices in the query.
Is there a way to create a new context outside the baseclass which I can attach the CurrentUser object to? I have tried ctx.Attach(CurrentUser) with no luck.
You may wonder why I don't include UserOffices. This is simply because there are very many relations to different tables and I don't want to include them all since it differs between my web pages what relations are needed.
Any ideas?
You can try to Attach your entity and then explicitly load property:
ctx.Attach(CurrentUser);
ctx.LoadProperty(CurrentUser, u => u.UserOffices);
I'm not sure if this works with POCOs.
You can also query for object again with Includes specifing navigation properties you need.
The other choice is simply load UserOffices with Linq-to-entities query restricting where condition to current user.
Related
There's a JSF 1.2 application with no way to switch to another version/technology in the observable future. It's often needed to show a small (modal) form that needs some state kept across several requests. After the work is done (confirmed or canceled) this state is not needed until the form opens again. There are a lot of such forms and session objects (separate per-form session beans or members of special huge session beans) are used for keeping their state. The sessions may last long enough, probably the whole working day. So a lot of objects unnecessarily load the session scope.
Is there a simple, standard way of cleaning a session object when it's no longer needed? What are your solutions regarding to that?
# Alex,
As you have mentioned that you have multiple view/page that you want to render/preserve in multiple requests and that remain persist until user session is not expire .
This is only because bean scope is session , May be you have did it is to avoid multiple db call to achieve performance just avoid reloading same info from database on each request.
I think you create a collection in user session bean or any other session bean where you find best (as per your choice but I will advise to create New Bean for only this purpose).
In this collection you just put your model data what you want to display on page do not register this bean in context file. persist the object where you required like you have three pages .P1,P2 & P3 and after P3 you want to remove model1 (your pojo)from session then on navigation event just remove model1 from collection .
//Sample code which help to understand what I am saying
#Session
UserBean {
Map tempBean<Obejct,String>=new HashMap<Object,String>();
//just for example suppose you want to load Model1
public Model1 viewP1() {
if(tempBean.get("P1info")==null){//key for P1 view
Model1 m1=db.getP1info();
tempBean.put("P1info",m1);
}
return (m1)tempBean.get("P1info");
}
}
To remove the Model1 data from session just set the value as null for key "P1info" in case of above code, You can use WeakHashMap,If you do not want to remove key from Map.But make sure to delete value part on your trigger of event after which you do not want to persist the Model1 value in session.
I hope this will work in your case .Please let me know in case of any problem in implementation since I have not shared working code ,but only showing concept.
Try to give a look here
link
I would run a remove on all the object once "the work is done".
I have started working out with Entity Framework (EF) for an MVC n-tier application. It would seem that very obvious that this being a web application (which is stateless), I would have to use detached object models. There is no ambiguity with doing an Add operation. However when doing an edit there are here are two ways
Fetch the original object in context, attach the updated object and
then save to database. Something like mentioned in answer to this
question
EF4 Context.ApplyCurrentValues does not update current values
Set individual modified properties explicitly using the IsModified property of individual fields of the object like
mentioned in this article
http://msdn.microsoft.com/en-us/data/jj592677.aspx
Method 1 has disadvantage of having to load object into memory from database each time an update needs to be performed.
Method 2 would require having to manually pass which fields to be set as IsModified to true from wherever the object an be updated. So for e.g. for each object, I may need to create a boolean collection object for each field of the object.
e.g.
SaveEntity(EntityClass e, EntityStateClass ec)
{
context.Entry(e).Property("Name").IsModified = ec.NameState;
context.SaveChanges();
}
class EntityStateClass{ public bool NameState;}
I would prefer method 2 simply for the sake of performance but I am hindered by the n-tier architecture and repository pattern I am using. My Repository interface restricts save method for any object to be
SaveEntity(EntityClass e);
So I cannot pass the "state" object. Context class is not available and should not be available outside DAL. So I cannot set property outside. Is there any "proper" way to achieve this ?
Note: Self-Tracking Entity is also out of question since I cannot send entities with state to client (the browser) since I am intent on keeping the html lightweight.
EDIT: After a lot of thinking, I am trying to use following mechanism to keep track of modified state for each field in my domain class
Declare a partial class for entity class.
For each field that is updateable, declare a boolean property like "IsModified_FieldName"
Set the "IsModified_FieldName" property when the field is set.
However for this I need Entity Framework to generate explicit properties for me instead of implicit properties that it auto-generates. Does EF provide an handle to do this ?
Here is sample code of what I am trying to achieve
//Save Method for class EntityClass.
SaveEntity(EntityClass e)
{
context.Entry(e).Property("Name").IsModified = e.IsModified_Name;
context.SaveChanges();
}
//EntityClass is class autogenerated by EF
public partial class EntityClass
{
//This is auto-generated property by EF
public string Name {get; set;}
/* This is what I would like EF to do
private string name;
public string Name
{
get {return Name;}
set {
name = value;
//this is what I would like to do
this.IsModified_Name = true;
};
}
*/
}
//This is another partial definition for EntityClass that I will provide
public partial class EntityClass
{
//This property will be set to true if "Name" is set
public bool IsModified_Name {get; set;}
}
PS: It seems the information I have provided is not sufficient and therefore there are no responses.
I am using DbContext (Database first model)
EF auto-generates the class files for me. So each time I update my database, the class files are regenerated.
To your concrete question: The entities are generated by a T4 template and it should be possible to modify this template (which is in text format) to generate the entities in a way you want to shape them.
But I have a few remarks about your concept:
In a web application data are usually changed by a user in a browser. To have a definite knowledge what really has been changed you need to track the changes in the browser (probably by some Javascript that sets flags in the data (a ViewModel for example) when a user edits a text box for instance).
If you don't track the changes in the browser what happens? The data get posted back to the server and you don't know at the server side (with MVC in a controller) which property has been changed. So, your only chance is to map all properties that has been posted back to your EntityClass and every property will be marked as Modified, no matter if the user really did a change or not. When you later call SaveChanges EF will write an UPDATE statement that involves all those properties and you have an unnecessary overhead that you you want to avoid.
So, what did you win by setting individual properties instead of setting the whole entity's state to Modified? In both cases you have marked all properties as Modified. Exceptions are partial changes of an entity, for example: You have a Customer entity that has a Name and City property and a view that only allows to edit the Name but not the City and a corresponding ViewModel that only contains a Name property. In this case your procedure would only mark the Name property of the Customer entity as Modified but not the City. You might save here a little bit because you don't save the City property value to the database. But you still save the Name even if it didn't change.
If you use solution 1 (ApplyCurrentValues) you have to load the entity first from the database, yes, but it would only mark the properties as Modified that really changed compared to their values in the database. If the user didn't change anything no UPDATE would be written at all.
Keep in mind that you are only at the beginning to implement your concept. There are other changes to the data that can happen in the browser than only scalar property changes, namely relationship changes. For example a user changes the relationship from an Order to a Customer or you have a view that has an Order and a collection of OrderItems and the user cannot only edit the Order header but also edit the OrderItems and remove and add new OrderItems. How do you want to recognize when the data come back from the browser to the server which collection item has been added and which has been removed - unless you track all those changes in the browser and send tracking information back to the server in addition to the actual data or unless you reload the Order and OrderItems from the database and merge the changes into the original entities from the database?
Personally I would vote for option 1 for these reasons:
You can use real POCOs that don't carry additional tracking information. (BTW: I have some doubt if you aren't reinventing the wheel by implementing your own tracking that EF change tracking proxies provide out of the box.)
You don't need to track changes in the browser which can become quite complex and will require Javascript in every Edit view to write change flags into hidden form fields or something.
You can use standard features of EF without having to implement your own tracking.
You are required to load entities from the database when you want to update an entity, that's true. But is this the real performance bottleneck in a web application where data have to run through the wire back and forth (and reflection (which isn't really known as to be fast) is involved by the model binder)? I have nothing said if your database is remote from the web server and connected by a 9600 baud modem. But otherwise, your plan is not only premature optimization, it is kind of premature architecture. You are starting to build a potentially complex architecture based on "it could be slow" to solve a performance problem that you actually don't know of whether it really exists.
I'm really confused by this... still.
I asked a similar question to this a while before, but i'll ask it even simpler now.
I see this in a lot of samples and tutorials. How could you put [Bind(Exclude="ID")] on an entire Model, and expect to do Edits on the model? If you get pack all the properties of a model on a POST but not the ID, then how do you know which ID to edit?
Even if i'm using ViewModels... i'm probably creating them without IDs. So in that case... also... how do I know which ID was updated on an Edit?
Yes, i understand that there is a "security" element to this. People can hijack the ID... so we need to keep people from updating the value during a POST. But... what is the correct way to handle edits then? What's common practice?
I feel like i'm missing something VERY trivial.
In MVC requests are processed by the model binder when the client makes a request. If you include models on your controllers then, as far as I'm aware, you actually have to specify the model you wish to bind to by prefixing your arguments with the model name (unless you only have one argument which is the model)
SomeModel_ID
Now, in some cases you might want to exclude certain properties from being bound to because they pose a security risk, which you seem to be happy with as a concept. We will exclude ID on the model, preventing any client request from posting this value in plain text.
Now why might we exclude an entire model? Well not all controller arguments are pre-processed by a model binder. RedirectToAction for example does not pass through the model binder, so it is conceivable in this instance for you to create a new model in a POST controller action, and redirect to a GET controller action, passing along a sanitised model. That model cannot be populated by the client, but we are free to populate it ourselves on the server side.
The only time I bind to a model is when I have a view model and an associated editor for that model. This makes it really easy to inject a common editor into a page and to encapsulate those properties. If you have to exclude certain properties from being bound to I would argue that you are doing it wrong.
Update
Following your comments I think I can see why you might be confused. The model bind excluder prevents the client from ever setting a model property. If you need this property to do your updating then you simply can't exclude it. What this does mean then is that the user could potentially post back any ID. In this case you should check that the user has permission to be modifying any objects or database records associated with this ID before serving the requested update. Validating the arguments is a manual process. You can use data annotations for validating inputs, but this isn't likely to help very much with access permissions. It's something you should be checking for manually at some stage.
You know the ID because it's passed to you through the page address. So:
http://yoursite.com/admin/users/edit/20
Will populate your ID parameter with 20. If it's used in a POST (ie, the information is filled in), just manually fill in the ID field and pass it to the database controller in whatever manner you have devised.
This is also immune to (trivial) hijacks because if they were to write some other ID besides 20, they wouldn't be updating the user with ID 20 now would they? :)
We have our POCO classes setup using Data Annotations.
For one of these classes, we invole more than one view for the user to populate all of their data. For example if it were a class with username and password as properties we would on the first page get the user to specify their username and on the second page specify their password.
Now, if i use the full POCO class (which requires that both username & password are supplied) then when we ask ModelState.IsValid were get false since the password hasn't yet been supplied, but we know that the password is going to be supplied on the next page!
Is there a generic way for us to validate those elements of the model for which values should have been provided rather than the whole Model? I know that i can remove the errors for individual items from the ModelState.
I know that we could separate out the model elements to have separate models for each page part of the entry that is being performed but this feels like we are changing the underlying class to fit more with the view.
Regards
Jamie
I believe the approach here by Steve deals with this
http://blog.stevensanderson.com/2010/02/19/partial-validation-in-aspnet-mvc-2/
in essence he filters out those keys for which there are no incoming values.
Try putting the validation on the ViewModel classes. Each view will have its own ViewModel class. One with the username, the other with the password. Don't use the model until you gathered all the data you need.
I have created a create view within my MVC 2.0 Application and by default it included a field for the integer ID Column.
This is definitely a field i do not need.
If i remove the field and use updatemodel when trying to create the object in code, will something break because it doesnt see my ID column data being passed in, even though it is auto increment?
Also, i noticed that in the NerdDinner example, updatemodel was used and after that the repository.save method was called.
I thought that updatemodel would save the object to the database..why then call the .save method afterwards? Or have i missed something?
Any help with this would be appreciated.
Cheers
As I understand it, the UpdateModel method will blow away all data in the object. This is because MVC is round-trip based. Anything that goes out should come back if you need to keep state. See this question for more details.
A better way to handle this scenario in my opinion is to have an input model class as an Action parameter which is passed to a service call to update the domain entity in the DB. (Or this mapping code could be right in the action method if you really want.)
Also please be aware of the security vulnerabilities that could be introduced by binding directly to your DB model.