entity framework code first inverse property generated column name - ef-code-first

For simple FK I could change the generated column name by using
[ForeignKey("CustomList1")]
public int? CustomList1ID { get; set; }
public virtual CustomList CustomList1 { get; set; }
But for inverseProperty (as I have multiple customList, how to control the generated column name for the database?
[InverseProperty("CustomList1")]
public virtual List<Customer> CustomerCustomList1 { get; set; }

[ForeignKey("CustomList1")] Does not change the generated column name.
If placed on the navigation property, it specifies the name of the field used to retreive the correct entity.
If placed on the field property, it specifies the associated navigation property that use this field as FK.
If you want to change the column name generated, you should use :
[Column("YOU_COLUMN_NAME")].

Related

How to use a class to create the SQLite table and ignore the fact that it is a List<ChildrenObjectModel>?

I'm using a class to generate an SQLite table, but I also want to use it as ItemSource for a two levels ListView (A listview with sub items).
This works for the ListView:
public class ParentModel:List<ChildrenModel>
{
[PrimaryKey]
public string uid { get; set; }
public string name { get; set; }
[Ignore]
public string attributeA { get; set; }
public ParentModel() {
}
}
But when I do mySQLiteConnection.CreateTable<ParentModel>(); it throws an Exception because the Object is a List<>.
I can [Ignore] attributes, but is there a way to ignore the fact that the the class is a List<>?
I can also create a List variable inside the model and [Ignore] it, but this wouldn't work for the ListView.
The only solution I can think is creating two classes with the same attributes, one being a List<> and the other one not.
But I really don't like this idea.
Not sure why you want to inherit from List<ChildrenModel>. You should make the ChildrenModel class a class that can create a table, and then that table would have all of the ChildrenModel items. Then in ParentModel you could have a public property of type List<ChildrenModel> which you can load from the ChildrenModel table. You would want to ignore that property as SQLite can not store a List. You can then access your populated List through the public property for the List<ChildrenModel> in the ParentModel class. That's what I would do anyway.

Auto generated unique number column on each update

I'm using Asp.Net MVC 5 + Entity Framework 6. Suppose I have this model:
public class ModelName
{
[Key]
public int Id { get; set; }
public int UniqueColumn { get; set; }
}
Now I want the UniqueColumn to be updated whenever I use db.SaveChangesAsync(); (meaning on both INSERTs and UPDATEs).
I tried to use DatabaseGeneratedOption.Identity but it won't update after the insert. I tried setting it to 0 but it gives me an error indicating that I can't modify an Identity column.
What do you mean by "to be updated"? You need to make it +1 on each action?
IF that is the case, try to make it static and access by class name, so it will not depend on object of this class. After update or insert action just do
ModelName.UniqueColumn++;

Dynamic Data Web Site, how to leave out columns?

I used VS 2012 to create a Dynamic Data Web Site using the standard built in template. Using EF I have added the database to the project that I want to use, and only selected the tables I saw fit for managing data through a web site. On the first page, you get the list of tables, when you click on one of those tables, it brings up a list of everything that's in that table(rows and columns). I'm very new to doing this type of thing and I'm wondering how I can make it so only certain COLUMNS appear. I want to do this because when you click on a table, if there are more columns than a few, they drag way off the right side of the browser. So basically I just want to display only columns that I think will be relevant. BTW, this project is in ASP.NET using EF for the data model. I still want these columns to be viewable when you click on the "Details" link for the row you want to see, I just want them to not show up in the list view. How can I do this, and what files do I need to modify?
You can leave out columns by using the [ScaffoldColumn(false)] data annotation attribute. I have a similar case where I do not want to include the CreatedBy, CreatedOn, UpdatedBy, and UpdatedOn columns. See the code sample to see how to exclude them.
using System;
using System.ComponentModel.DataAnnotations;
namespace S1000DDecision.Data
{
/// <summary>
/// Summary description for Category
/// </summary>
[ScaffoldTable(true)]
[MetadataType(typeof(CategoryMetadata))]
public partial class Category
{
}
public class CategoryMetadata
{
[ScaffoldColumn(false)]
public Object CreatedBy { get; set; }
[ScaffoldColumn(false)]
public Object CreatedOn { get; set; }
[ScaffoldColumn(false)]
public Object UpdatedBy { get; set; }
[ScaffoldColumn(false)]
public Object UpdatedOn { get; set; }
}
}

Why entity framework does not delete record when setting navigation property to null

I am new with EF Code First and have some troubles with it.
Here my Model
public class User
{
public string Id { get; set; }
public string Name { get; set; }
public virtual Address Address { get; set; }
}
public class Address
{
public string Id { get; set; }
public string Street { get; set; }
public string Nr { get; set; }
}
What I want is, if I write the following code:
user.Address = null;
the related Address (record in database) should be deleted, but it is not! It removes only the foreign key in Users table. Also when I assign a new Address:
user.Address = new Address() { ... };
it is created a second record in database, why?
I want:
if assign null to user.Address the database record should be deleted
if assign a new Address object to user.Address it should replace the existing records data with the new one
How can I solve this?
If you need to delete an entity you need to mark it as deleted. Setting a navigation property to null will not delete the related entity. Note that there may be many navigation properties (different entities) pointing to the related entity and they all would be affected in the scenario you are describing.
Because you create a new Address a new entity is created. Then you set your navigation property to a newly created property this breaks the old relationship and creates a new one. Since the entity you created is not in the database it will be added. You also did not delete the old entity so it was not deleted from the database. If you just want to change property values of an entity just set properties to new values and invoke SaveChanges. This should update data in the database.

Deleting rows from a collection using ef code first

I have the following domain model:
public class Campaign
{
public virtual long Id { get; set; }
public virtual string Name { get; set; }
public virtual ICollection<Content> Content { get; set; }
}
public class Content
{
public virtual long Id { get; set; }
public virtual string Body { get; set; }
}
This is configured:
modelBuilder.Entity<Campaign>().HasMany(x => x.Content).WithOptional();
In my service I have the following code:
Campaign campaign = campaignRepository.GetById(id);
This loads the campaign and any associated content items into the collection which is great. The issue comes with the following code:
campaign.Name = "new value";
campaign.Content.Clear();
unitOfWork.Commit();
This does not delete the content rows from the database. It actually sets the foreign key in the content table to null for the affected rows but it does not delete the rows.
I then tried to modify the configuration to:
modelBuilder.Entity<Campaign>().HasMany(x => x.Content).WithRequired();
This would simply give me the following exception: A relationship from the 'Campaign_Content' AssociationSet is in the 'Deleted' state. Given multiplicity constraints, a corresponding 'Campaign_Content_Target' must also in the 'Deleted' state.
There must be a way to delete rows from the content collection. I must be missing something. Any help is appreciated.
You will have call the Remove method on the corresponding DbSet for each entity instance.
foreach(var content in campaign.Content)
{
dbContext.Contents.Remove(content);
}

Resources