How to make an Entity Framework property NOT NULL, but not required in form submission - entity-framework

I'm using Entity Framework 4.1 with a code-first model. A common pattern is that many objects reference the user who owns them, eg.
public class Item
{
public User Owner { get; set; }
}
This creates a nullable column in the DB, but since every Item must have an owner I want the column marked NOT NULL. If I use the [Required] attribute then submitting the form to create an Item results in an error. That field is never set through a form, only manually in code.

It is generally recommended to create separate view models for such situations. Using database models as view models for input forms is seen as an anti-pattern.
Make a ItemViewModel that has the same properties as Item and relevant data validation attributes. You may want to use a library called Automapper to automate the boring property-copy-code needed in those cases.

Related

Entity Framework Database First - Map to Generic List

I'm using Entity Framework - Database First in my project. My model has a view with only one VARCHAR column:
CREATE VIEW MyView
AS
SELECT 'Eris' Eris
FROM MyTable
By default, this view gets mapped to its own entity with just one property:
public virtual DbSet<MyView> MyViews { get; set; }
How can I change this so that the view gets mapped to a List of strings instead:
public virtual List<string> Eris { get; set; }
Unfortunately EF does not support mapping collections of value types. If you really want to implement this scenario then you might want to look into other ORM frameworks that have this feature like NHibernate.
If that's not an option and you have to stick to EF then you're forced to create an entity with one property like you mentioned in your question.
The entity model represents one element in the table.
When you retrieve data from the table, you will get a list of entity model objects.

Any Point to the DbSet Property Name?

public DbSet<Lecture> Lectures{ get; set; }
Does the property name here matter at all? It seems that if I want to use the model, I use "Lecture". The generated table is just a plural of whatever is in <>, e.g., if I understand correctly, I can change "Lectures" to "Leprechauns" and my table will still be called "Lectures" based on <Lecture> and I will use context.Lectures to select from it. Does the property name have any point?
I didn't find the answers in this tutorial or on msdn.
Edit: Upon further testing - the db table name is based on the model name in the angle brackets, but to actually select from the db (in the C# code), you use the property name specified in DbSet propertyName. Still would like to hear how this works in detail.
Entity Framework builds a model of the database, where each class/model represents an entity type, and each DbSet represents a set of entities of a single type. When you declare a DbSet<T> property in your DbContext, that tells EF to include the class of type T as one of the entity types, and it automatically includes any other connected types (e.g. navigation properties) in the object graph as well.
All this to say, the name of the property itself probably doesn't matter. In fact, you could use the Fluent API to add entity types as well, not declare any DbSet properties if you wanted, in which case you'd use context.Set<T> to retrieve the DbSets. The properties are really just for convenience.
Maybe this is helpful as well: https://msdn.microsoft.com/en-us/data/jj592675.aspx
DbSet corresponds to a table or view in your database, So you will be using your DbSet's to get access, create, update, delete and modify your table data.
By the way you can remove the convention:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
The property name matters. The EF translates the name of the property into the name of the table. If the property name is not the same with the table name you'll get an error. Unless you specifically tell the builder the name of the table like this:
public void Configure(EntityTypeBuilder<Lecture> builder)
{
builder.ToTable("License");
}

How to model a n to m relation with an attribute in Entity framework without adding the extra table

I'm pretty new to the Entity framework and I'm modelling this simple structure:
With this model what I have is a Users class with a property UsersGroups (a collection of UserGroups objects).
I would like to have a Users class with a property like Groups with type Tuple or something like this (a new PriorizedGroup class, etc) that is much more related with the bussines.
Is this possible with the Entity framework?
Thanks in advance.
EDIT: If I were modeling the bussines objects I would create a User class with a Groups property that contained all the groups the user pertains with an extra property to store its priority (with a tuple, with an inherited class, as you wish). The thing is that I feel that the objects created by the Entity framework resemble the SQL structure, not the business structure.
Not directly. EF can map the relation only in the way you see it at the moment but you can add your custom behavior to your partial part of the entity. The simple way is something like
public partial class Users
{
public IEnumerable<PrioritizedGroup> Groups
{
get
{
return UserGroups.Select(ug => new PrioritizedGroup
{
Priority = ug.Priority,
Id = ug.Group.Id,
Name = ug.Group.Name,
Description = ug.Group.Description
})
.OrderBy(g => g.Priority);
}
}
}
To make this happen directly in EF you need some advanced mapping technique which will require you to modify EDMX source code directly (either DefiningQuery or QueryView) and it will make the entity read only (you will need stored procedures for modification).
To make the collection exposed on Users updatable you would probably need to use ObservableCollection and transfer all modifications triggered by ObservableCollection back to original UserGroups collection. Once you have something like that implemented you can hide original collection.

What is the meaning of the "Pluralize or singularize generated object names" setting?

When setting up a new Entity data Model, there is an option to
[x] Pluralize or singularize generated object names
I have noticed this is an option in LINQ as well. Also, now that I am studying the ADO.NET entity framework, I noticed it also has 'DEFAULT' to 'pluralize or singularize generated object names'
What is the result of not checking/allowing this option when setting up the 'Entity Data Model'.
What Advantages/Disadvantages/issues will I face by making a selection one way or the other?
If you check Pluralize or singularize generated object names, the set in the class context.cs genrated by EF will be named in the format:
public virtual DbSet<SomeTableName> SomeTableNames { get; set; }
if not check, it'll be named:
public virtual DbSet<SomeTableName> SomeTableName { get; set; }
Advantages/Disadvantages IMHO:
I would like to see collection set be named ending with 's', such as dbset colleciton of Employee class of Employee Table named Employees, so I'll check the option. But I guess maybe someone would like to treat the dbset as a table, so he/she would like to name it same as table name Employee.
No problem at all, except that you'll probably want to do it manually. Usually, you want entity names singular and entity set names plural.

Saving Dropdown list selection with Entity Framework in ASP.NET MVC solution

I'm looking for advice on a decent pattern for dropdown list selection and persistence of the selection with POCO EF please.
I have a list of IEnumerable<Country> in my view model where Country is a POCO loaded via EF. There is an Address property on the view model that takes the current or user selected value on it's Country property. Within the view I display these via a Html.DropdownListFor() thus:
Html.DropDownListFor(model => model.Address.Country.Id, new SelectList(Model.Countries,"Id","Name",model.Address.Country.Id)
So far so good and it all works on postback with the default ModelBinder providing me with a view model with the Address.Country populated. However Address.Country is of course only populated with the Id field with default model binding.
Trying to send the Address update back to the DB through EF blows up as this is seen as a new object which doesn't have it's full object graph loaded, only the Id set.
Now I can fix this by loading the full Country object from the db into the Address.Country property on postback before saving based on the selected Id. But this seems like a lot of hard work for anything beyond a simple object graph.
The most "elegant" solution I could think of would be a custom model binder for Country but then that would require the Model Binder to know about the repository for retrieving the full EF object which doesn't seem right to me. I'd also have to repeat this for all other Entities used in Dropdown lists.
Hope this makes sense and any feedback on how others are doing this would be appreciated.
If you set Address.Country to an object, EF expects it to be a full object that's part of the current context, but EF does recognize foreign keys: If your Address object has both a CountryID property and a Country property, it should accept Address.CountryID being set as long as Address.Country itself is null.
In your Address class declare country as virtual
public class Address
{
public virtual Country Country;
}
try this and let me know if it works, Virtual supports lazyloading and you don't have to query explicitly