mvc3 entity object with extra field not saved - entity-framework

I am writing an mvc3 application with Entity. I am brand new to .net and entity, so this question may be basic.
I have a model in that represents an object that gets saved to the database. But I would like to have an extra field display on the create and edit forms that is not saved to the database.
Is there a way to specify that a field is not saved with the rest of the object? Also, is there a way to make a field required on create and not on edit?
I would just hard code it, but I would like to include it in the validation that can be set on the entity models.
I am using Entity code first.

you can use viewmodels for displaying or editing, while saving map your view model to domain model(excluding the non-desired fields) and then save it. You can use a tool auto mapper to map your view models to domain models.
say for example you have a domain class person
public class Person
{
public string Name {get; set;}
public string Address {get; set;}
}
then you make a view model
public class VMPerson
{
public string Name {get; set;}
public string Address {get; set;}
public int Age{get;set;}
}
fetch data into your view model and pass it to your view the query may look like
var q = (from p in db.Person
select new VMPerson{
Name = p.name,
Address = p.address,
Age = 16
}).SingleOrDefault();
return q;
in your view the age will also be displayed, then on post
[HttpPost]
public ActionResult Person(VMPerson vmperson)
{
Person p = new Person()// your domain object
// mapping part here
p.name = vmperson.name;
p.address = vmperson;
TryUpdateModel(p);
db.Person.Save();
}

Related

Using Entity Framework to create a custom model that is not a model of any table in a database

I am using the .NetCore Entity Framework for the first time and want to know if the it is possible to generate a custom model.
When setting up the app, EF created all the models from the database. That is fine and expected.
However, I now created a new controller that returns data that is the result of a complicated linq query.
All my other controllers return a model like this:
return View(characterList);
where characterList is an actual model of a database table.
But how would I create a brand new custom model that does not represent any table in the database?
Thanks!
You would first simply create the model you want to have in your code.
For example:
Public class NewModel {
Public String Test {get; set;}
}
Then you can use your context and the power of linq/select to query in your new model.
Something like this:
List<NewModel> list = dbContext.Set<OldModel>().Where(...).Select<NewModel>(x=> new NewModel(){ Test = x.OldTestString }).ToList()
And so you get a list of the new model. You could e.g. include other tables and join them in the query to make it more complicated. But this example should give you a starting point.
If the model you are explaining is supposed to be used only for the views consider creating a ViewModel which is basically a class that contains only the properties needed for the view usually without any logic or only with a logic immediatelly necessary for displaying in a view.
For example, you'd create a new class, let's say CharacterVM
public class CharacterVM
{
public string Name{ get; set; }
public string CharacterType {get; set; }
public bool Invincible{ get; set; }
}
In your view you'd use CharacterVM which has all the properties exposed in the CharacterVM class
#model CharacterVM
The most important step is remapping the properties from your database model (let's say it is called Character) where all you have to do in that case is to remap the properties of the Character to the properties of the new instance of CharacterVM you'd pass to the view.
public IActionResult Index(int idCharacter)
{
var character = db.Characters.SingleOrDefault(c => c.idCharacter == idCharacter);
var characterVM = new CharacterVM()
{
Name = character.Name,
CharacterType = character.Type.Name,
Invincibility = false
};
return View(characterVM);
}

Can the Entity Framework Code First generate properly for System.Drawing.Font or Dictionaries?

I am trying to generate a CMS using the Entity Framework Code First. I have a TextBox class that I'd like to have a System.Drawing.Font property or a Dictionary Property. Can the Entity Framework Code First generate properly for System.Drawing.Font or Dictionaries?
EF CF is a code-based ORM (Object-Relational Mapper). It handles the storage and retrieval of data held in classes in your app to and from tables in a database.
If you want to store/retrieve data from your forms, you should create "model" classes - these are just simple classes that contain properties for the values you want to store in your DB. For example:
public class Page
{
public Guid ID {get; set;}
public string Title {get; set;}
public string Body {get; set;}
public string FontName {get; set;}
public int FontSize {get; set;}
}
You then create a DbContext class that contains DbSet instances of the type of your model classes:
public class StorageContext : DbContext
{
public DbSet<Page> Pages {get; set;}
}
Now, EF will figure out the structure of the data you want to store and handle all the DB operations to load/store your data to your DB.
You should be able to write pretty much all your model and DB code (in a separate library in case you need to reuse).
Note: I also strongly encourage you to add an additional level of abstraction and create a Repository class so that your UI code needs know nothing about HOW you're storing your data - this will allow you to change to a completely different storage engine later without having to touch your app code! For example:
public class PageRepo
{
StorageContext _ctx = new StorageContext();
public Page GetPageById(Guid id)
{
...
}
public void StorePage(Page page)
{
...
}
}
You then use your StorageContext (or, better still, your repository) and Model classes to get/store data from/to your DB and copy those values into the necessary fields in your forms, peprforming any data validation before you store data, of course ;)
HTH.
Entity framework allows you to only map few predefined types. That is because it is an ORM and data types that are common to many RDBMS are supported. You can how ever break the complex type such as Font to its primitive properties and map to an entity.
Eg
public class Style
{
public Guid ID {get; set;}
public string FontName {get; set;}
public int FontSize {get; set;}
// other properties
}
In your UI layer you would have a TextBox that will use the style to build a Font.
public class TextBox
{
public TextBox(Style style)
{
Style = style;
}
protected Style Style {get; set;}
public Font FontSize { get { return new Font(Style.FontName, Style.FontSize); } }
// other properties
}

ASP.net MVC.2 return multiple objects to strongly typed viewmodel

I am new to MVC and using the repository pattern in an attempt to select data containing two objects to return to a strongly typed viewmodel,
Im getting a bit stuck with what the best way to do this is,
The two tables are related by a customer id field, i have a repository interface set up, and a display template that is strongly typed to a viewmodel that contains properties for the Customer and a Customer Site object, all i need is to display a list of customer sites along with the relevant customer name from the customers table.
In the display template i have the following
<%= Html.DisplayFor(x => x.Customers.CustomerName) %>
<%= Html.DisplayFor(x => x.Customers.Site.AddressLine1) %>
I have this display template working but my model is empty.
Where im getting confused is how to define this data in the interface and repository, and how to return the data to my model, to simply return my list of customers i use this in my interface
IQueryable<Customer> Customers { get; }
Then a simple LINQ select.
But as this data will contain both customers and customer sites im unsure how to define this in the interface?
Also will a LINQ join be a suitable method to return this data to my viewmodel? something like
var Customers =
from c in customers
join cs in customerSites on c equals cs.CustomerId into ps
from p in ps
select new { Customer = c, cs.CustomerName };
UPDATE=========
This is the code i am using in the view model that is stronly typed to the display template,
public class CustomerViewModel
{
public int Id { get; set; }
public string CustomerName { get; set; }
public string PrimaryContactName { get; set; }
public SiteViewModel Site { get; set; }
}
Its how to populate the model in the repository/controller with both objects to display in a list that im struggling with.
You may have done soem of the following steps already so please ignore if you have..
1 creat a ViewModel folder in your solution.
2 Create a base view model .... might look like this ->
public class BaseViewModel
{
public PageProperties PageProperties { get; set; }
public User User { get; set; }
}
3 Setup a view model for your controller action maybe like so ->
public class ProjectVM : BaseViewModel
{
public ProjectPoco project { get; set; }
}
4 In your controller get your data from your repositiory and pass it to an instance of your view model like this ->
var contextVM = new ProjectVM();
contextVM.project = ObjectExtensions.Convert<ProjectPoco>(tbl.Single(id));
contextVM.PageProperties = new PageProperties
{
Heading = contextVM.project.Name,
SubHeading = "Details for" +
contextVM.project.Name
};
return View(contextVM);
5 set your views model to be that of your view model ->
#model
NerveCentre.ViewModels.ProjectVM
6 use your viewmodel to pull data out into your view ->
#Model.project.Description
A quick and rough description of passing data to your view via a view model. hope I didnt miss anything out.
As for the data.. looking at how you have the model (Customers.Site.AddressLine1) would it not just be possible to pass the Customers from your query to your view model?
So your viewmodel might look something like..
public class SomeViewModel: BaseViewModel
{
public List<Customer> Customers { get; set; }
}
If you let us know what you are using for data access then we might be able to help more with the specifics of getting the data out of your tables and into the format you want?

Password confirmation field -- extension or composition

Good day!
I've, say, simple LINQ2SQL entity called User. I need a profile page where password confirmation field needed. I don't want to add this field to my db or entity. I'd like to add ViewModel class. My firt attempt is like this:
[MyClassLevelAttributeToCheckPasswordAndPasswordConfirmation]
public class ProfileUser
{
public User UserEntity {get; set;}
[DisplayName("Password confirmation")]
public string PasswordConfirmation {get; set;}
}
My User class has its own validation and metadata.
Is there any better solution?
Thanks in advance!
Don't use any of your model classes inside the views. Use plain view models:
[MyClassLevelAttributeToCheckPasswordAndPasswordConfirmation]
public class ChangePasswordViewModel
{
public string Password { get; set; }
[DisplayName("Password confirmation")]
public string PasswordConfirmation {get; set;}
}
As you can see we put only the properties relevant to changing a password view (or whatever view you are implementing). This way you can have a fine grained validation control in the context of the given view. AutoMapper could help you to get back your model from the view model.

ADO.NET Entity Data Model - Adding custom properties

I am new to using the ADO.NET Entity Data Model tool. I have a table in my database that has three properties (FirstName, LastName, Age). I need to add a field to this entity called IsChosen. However, I cannot add this column in the database.
How do I add custom properties to entities generated through this tool?
Thank you!
The Entity Data Model tool creates partial classes.
You can extend those partial classes in another source file. You just need to make sure your section of the partial class lives in the same namespace as the Entity Data Model generated classes. For example:
Tool Generated Code
namespace Your.Generated.Classes
{
public partial class Stuff
{
public string Name {get; set;}
public int Age {get; set;}
}
}
Your Seperate Code File
namespace Your.Generated.Classes
{
public partial class Stuff
{
public string NonDatabaseProperty {get; set;}
}
}