Automapper seems to be caching data - asp.net

Automapper version, which i am using in project is, AutoMapper, Version=6.0.2.0
When i run this for the first time, there is a record available in person object, which gets mapped to employee object. In the subsequent runs, though person object does not have any data, employee object holds the previously stored data and it appears to be cached data.
how can i get rid of this ?
Mapper.Initialize(cfg =>
{
cfg.CreateMap<Person, Employee>();
});
person pobj = new person();
pobj.FirstName = "Adam";
pobj.LastName = "Smith";
pobj.Address = "some address";
Mapper.CreateMap<Person, Employee>();
Employee emp = Mapper.Map<Employee>(pobj);

Related

Add objects to session

I need some clarity about session and how to add objects, because I think I do it the wrong way.
First I create a session to hold a list of Products:
Session["ShoppingCart"] = new List<Products>();
To add Products to the list, I do like this:
Session["ShoppingCart"] = new Products { ID = productId, Name = name };
I guess this isn't the right way?
I guess this isn't the right way?
Yes, this isn't the right way (please skip towards the last paragraph of my answer to know the correct way - which is not to use ASP.NET session at all). The correct way is to first get the object you stored inside the session by trying it to cast it to the same .NET type yo uhave stored inside the session:
var products = Session["ShoppingCart"] as List<Products>;
and then if this item is not null add the corresponding product to the list. We should of course make the necessary type check that the session actually contained a value with the specified key and that this value is of the expected type:
if (products != null)
{
var product = new Products { ID = productId, Name = name };
products.Add(product);
}
Of course we are using object references here which will only work if you are storing your session in-memory (sessionState mode = InProc) which of course is absolutely a terrible disaster and something you should never do in production. In a production environment you are probably persisting your session in a session server or even SQL server, aren't you? In this case it is more than obvious that working with object references is a recipe for disaster. So in this case once you have added the new product to the session you should of course set back the new list value to the session which will serialize the object instance to the corresponding data store:
if (products != null)
{
var product = new Products { ID = productId, Name = name };
products.Add(product);
Session["ShoppingCart"] = products;
}
Now, after all this being said I must admit that using ASP.NET Session is probably the huge mistake you would ever commit in a real world application. So basically every time you are using Session["xxx"] you are doing it wrong. Simply search the entire solution for the Session keyword and just get rid of it.
In order to add itens to an existing list on the Session, you must first retrieve the list then add the object to it. Here's an example:
Session["ShoppingCart"] = new List<Products>();
List<Products> productsList = (List<Products>)Session["ShoppingCart"];
productsList.add(new Products { ID = productId, Name = name });
Session["ShoppingCart"] = productsList;

Saving changes of Entity Framework in Asp.Net

I have created an entity Appraiser and there are methods to select values, display data etc.
Now I want to save the changes made after data is displayed, I have a button named SAVE, which will be used to save changes.
I am not able to get how to save the changes of this Entity?
Entity name is Appraiser, and I have created methods like get AppriaserDetails etc in DAL, BL and used them in aspx.cs.
This is my code:
public void UpdateData(Appraiser appId)
{
var Appsave = context.Appraisers.FirstOrDefault(App => App.AppraiserId == appId.AppraiserId);
Appsave.AppraiserName = appId.AppraiserName;
Appsave.AppraiserPhones = appId.AppraiserPhones;
Appsave.AppraiserAppraiserCompanyId = appId.AppraiserAppraiserCompanyId;
Appsave.Address = appId.Address;
Appsave.City = appId.City;
Appsave.ProvinceState = appId.ProvinceState;
Appsave.Email = appId.Email;
context.SaveChanges();
}
If u want to insert new record, then can use
MyContext.Appraisers.AddObject(appraiserEntityObject);
MyContext.SaveChanges();
In case of update
if (appraiserEntityObject.EntityState == EntityState.Detached)
{
// In case of web, we got an existing record back from the browser. That object is not attached to the context yet.
MyContext.Appraisers.Attach(appraiserEntityObject);
MyContext.ObjectStateManager.ChangeObjectState(appraiserEntityObject, EntityState.Modified);
}
MyContext.SaveChanges();
Here MyContext is ur ObjectContext

How to save a related entity using Entity Framework in asp.net

I am pretty new to Entity Framework. I am getting an error as
An object with a temporary EntityKey value cannot be attached to an
object context
I think I am doing something wrong.
I have a Customer table and Address table where the Address table has customer's ID as foreign key.
I want to add a new address to the customer entity and keep in session and in next call I want to save it. this is only an example.
using (var db = new MyModel())
{
Customer cust = db.Customers.SingleOrDefault(c => C.ID == 1);
Address addr = new Address();
addr.Street = "123 super st";
cust.Addresses.Add(addr);
Session["customer"] = cust;
}
Customer SessionCustomer = (Customer)Session["customer"];
Customer.Comments = "Added new address";
using (var db = new MyModel())
{
db.Customers.Attach(SessionCustomer); //This throws exception: An object with a temporary EntityKey value cannot be attached to an object context
db.ObjectStateManager.ChangeObjectState(SessionCustomer, System.Data.EntityState.Modified);
db.SaveChanges();
}
Any help is appreciated. thank you.
Try using db.Customers.AddObject() for reattaching object to datacontext.
Take also a look at this: http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.addobject.aspx
Cheers

Returning a column from a linked table in LINQ to SQL

My problem is that I am trying to return a simple query that contains an object Story. The Story object has a UserId in the table which links to aspnet_users' UserId column. I have created a partial class for Story that adds the UserName property since it does not exist in the table itself.
The following query gets all stories; however, a pagination helper takes the query and returns only what's necessary once this is passed back to the controller.
public IQueryable<Story> FindAllStories(){
var stories = (from s in db.Stories
orderby s.DateEntered descending
select new Story
{
Title = s.Title,
StoryContent = s.StoryContent,
DateEntered = s.DateEntered,
DateUpdated = s.DateUpdated,
UserName = s.aspnet_User.UserName
}
);
return stories;
}
When the helper does a .count() on the source it bombs with the following exception:
"Explicit construction of entity type 'MyWebsite.Models.Story' in query is not allowed."
Any ideas? It's not a problem with the helper because I had this working when I simply had the UserName inside the Story table. And on a side note - any book recommendations for getting up to speed on LINQ to SQL? It's really kicking my butt. Thanks.
The problem is precisely what it tells you: you're not allowed to use new Story as the result of your query. Use an anonymous type instead (by omitting Story after new). If you still want Story, you can remap it later in LINQ to Objects:
var stories = from s in db.Stories
orderby s.DateEntered descending
select new
{
Title = s.Title,
StoryContent = s.StoryContent,
DateEntered = s.DateEntered,
DateUpdated = s.DateUpdated,
UserName = s.aspnet_User.UserName
};
stories = from s in stories.AsEnumerable() // L2O
select new Story
{
Title = s.Title,
StoryContent = s.StoryContent,
...
};
If you really need to return an IQueryable from your method and still need the Username of the user you can use DataContext.LoadOptions to eagerload your aspnet_user objects.
See this example.

ADO.NET Data Services: Non-Asynch Calls?

I have a question that I'm struggling with in ADO.NET Data Services:
When assembling an Entity for storage I need to get a related value from a lookup file. For example a person has a status code assigned of 'Pending' which is in a table called StatusCodes.
In Entity Framework, I'd need to set the value of person.StatusCode equal to an instance of the StatusCode. In the Entity Framework or in LINQ2Sql I'd so something like this:
var person = Person.CreatePerson(stuff);
var statCode = myContext.StatusCodeSet.Where(sc => sc.Description == "Pending").FirstOrDefault();
person.StatusCode = statCode;
// ...more code here...
myContext.BeginSaveChanges(SaveChangesOptions.Batch,
new AsyncCallback(OnSaveAllComplete),
null);
The query for the statCode won't work in ADO.NET Data Services and I get a runtime error saying the function is not supported. I assume it's because the statCode lookup is not an Async call.
However,
var person = Person.CreatePerson(stuff);
var query = from stat in myContext.StatusCodeSet
where stat.Description == "Pending"
select stat;
var dsQuery = (DataServiceQuery<StatusCode>)query;
dsQuery.BeginExecute(
result => tutorApplication.StatusCode = dsQuery.EndExecute(result).FirstOrDefault(), null);
// ...more code here...
myContext.BeginSaveChanges(SaveChangesOptions.Batch,
new AsyncCallback(OnSaveAllComplete),
null);
doesn't work either due to the Async nature of the query, the result won't be back before the person save happens.
Am I approaching this correctly?
Thanks
After sleeping on this I came up with the following:
var person = Person.CreatePerson(stuff);
var appStatPending = new StatusCode()
{
StatusCodeId = (int)StatusCodes.Pending,
Code = "Pending",
Description = "Pending",
EffectiveDate = DateTime.Now,
EnteredBy = "",
EnteredDate = DateTime.Now
};
myContext.AttachTo("StatusCodeSet", appStatPending);
person.StatusCode = appStatPending;
myContext.SetLink(tutorApplication, "StatusCode", appStatPending);
// ...more code here...
myContext.BeginSaveChanges(SaveChangesOptions.Batch,
new AsyncCallback(OnSaveAllComplete),
null);
I can create a local copy of the status code and link it into the context. It's important to new up the appStatPending rather than doing a StatusCode.CreateStatusCode() since doing that will add a new StatusCode to the database when the person graph persisted. For the same reason it's important to do the AttachTo("StatusCodeSet", appStatPending) since doing myContext.AddToStatusCodeSet() will also add a new entry to the StatusCodes table in the database.

Resources