I have simple Model defined as
public class Project
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int StatusId { get; set; }
public virtual Status Status { get; set; }
}
public class Status
{
public int Id { get; set; }
public string Name { get; set; }
}
So, currently If I try to create a new Project Entity with breeze, it initializes the navigation property "Status" with null. How can I initialize it with default value? Note that, I don't want any binding with drop down field for this field at least for create operation.
function createNewProject() {
return manager.createEntity('Project');
}
You can define a custom constructor for the Project entity type and set a default StatusId value in there. The Status navigation property will be set to the relevant status entity (assuming the entity is in the breeze cache). For example:
function Project() {
this.StatusId = desiredDefaultStatusEntityId;
}
var manager = new breeze.EntityManager('...');
manager.metadataStore.registerEntityTypeCtor('Project', Project);
Take a look at Extending entities for some more information on extending entities.
Related
i Have a Model Class
public class Student
{
public int StudentId { get; set; }
public string StudentName { get; set; }
public ICollection<SelectListItem> CourseList { get; set; }
}
and the
public class StudentContext : DbContext
{
public DbSet<Student> Students { get; set; }
}
and i try ti use it as
List<Student> sList = db.Students.ToList();
and i am getting following error
\tSystem.Data.Entity.Edm.EdmEntityType: : EntityType 'SelectListItem' has no key defined. Define the key for this EntityType.
\tSystem.Data.Entity.Edm.EdmEntitySet: EntityType: EntitySet 'SelectListItems' is based on type 'SelectListItem' that has no keys defined.
Please suggest where i am doing wrong.
Add [NotMapped] annotation to the LIST class
[NotMapped]
public List<SelectListItem> ListItems { get; set; }
NotMapped Code first convention dictates that every property that is of a supported data type is represented in the database. But this isn’t always the case in your applications. For example you might have a property in the Blog class that creates a code based on the Title and BloggerName fields. That property can be created dynamically and does not need to be stored. You can mark any properties that do not map to the database with the NotMapped annotation such as this BlogCode property.
[NotMapped]
public string BlogCode
{
get
{
return Title.Substring(0, 1) + ":" + BloggerName.Substring(0, 1);
}
}
You can refer to the link here on EF code first Data Annotations
You should not be attempting to store SelectListItem in the database, as this is MVC specific concept. Instead create a custom entity class and use it instead;
public class Course
{
public int CourseId { get; set; }
public string CourseTitle { get; set; }
}
public class Student
{
public int StudentId { get; set; }
public string StudentName { get; set; }
public ICollection<Course> CourseList { get; set; }
}
public class StudentContext : DbContext
{
public DbSet<Student> Students { get; set; }
public DbSet<Course> Courses { get; set; }
}
I use Asp.Net MVC, Entity Framework. I have a form it looks like below.
Here, dropdownlist is filled from a table(types). Checkboxes is filled from another table(test). Tables are like below:
public class Types
{
public int TypesID{get;set;}
public string TestName { get; set; }
public string TestExplanation { get; set; }
public int TestTime { get; set; }
}
public class Tests
{
public int TestID{get;set;
public string Name { get; set; }
public string Code { get; set; }
}
public class Types_Tests
{
public int Types_TestsID{ get; set; }
public int TypesID { get; set; }
public int TestsID { get; set; }
public virtual Types Types { get; set; }
public virtual Tests Tests { get; set; }
}
Types_test table is relation table between Types and Tests. When I click Kaydet button, it shuld save type and checked tests. I made this operation using ViewBag, javascript and hdnvalue.I added checked checkboz values to a hdntext. I made saving process like below:
[HttpPost]
public ActionResult Index(string drpType, string hdntesttypes)
{
var TypeList = Types.GetAll();
ViewBag.TypesList = new SelectList(TypeList, "Id", "Name");
var testypeList = testTypes.GetAll();
ViewBag.TestTypesList = new SelectList(testypeList, "Id", "TestName");
GenericRepository<TestDisabledTypes> testDisabledRepository = new GenericRepository<TestDisabledTypes>(_context);
if (!string.IsNullOrEmpty(hdntesttypes))
{
string[] disabletypesArray = hdntesttypes.Split(',');
using (TransactionScope trns = new TransactionScope())
{
for (int i = 0; i < disabletypesArray.Length; i++)
{
Test_Types types = new Test_Types ();
types.TestTypesID = Convert.ToInt32(disabletypesArray[i]);
types.TypesID = Convert.ToInt32(drpType);
testDisabledRepository.Insert(types);
}
trns.Complete();
}
}
return View();
}
It wokrs. But I search better solution for this process. Can someone give me any idea?
Thanks.
If you don't need additional attributes for your entity class, you don't need create link table.
Just define the following class, and EF will generate the link table for you automatically.
public class Type
{
public int TypesID{get;set;}
public string TestName { get; set; }
public string TestExplanation { get; set; }
public int TestTime { get; set; }
public ICollection<Test> Tests { get; set; }
}
public class Test
{
public int TestID{get;set;
public string Name { get; set; }
public string Code { get; set; }
public ICollection<Type> Types {get;set;}
}
Well, in EntityFramework if you want to create a many to many relation object you need to create new object of "linking" entity. Unfortunately, it is not possible to add first object, add second object and say "Guys, you are in many to many relationships. Are you happy then?" :) You need to create relation object, set appropriate fields in it (I think these are ids of two objects itself) and add it to relation collection (entity) in your model. But before doing so you need to be sure that objects with data you are linking with are already exists in database. Otherwise you'll get an error
Also it's not necessary to create manually transaction because EF does it for you automatically each time you get/save your data
I'm trying to create a model that can optionally refer to a parent of the same type, for example:
public class Category
{
public virtual long CategoryID { get; set; }
public virtual Category? ParentCategory { get; set; }
public virtual int UserID { get; set; }
public virtual string Name { get; set; }
}
As you can see there is an optional member called ParentCategory that is optional and refers to a class of type Category (i.e. the same type). As I'm sure you can guess, I'm trying to create a simple Category tree, where the root node(s) will not have a parent.
This results in the following error when the Entity Framework tries to create the database:
"The ForeignKeyAttribute on property 'ParentCategoryID' on type 'MyProject.Models.Category' is not valid. The navigation property 'Category' was not found on the dependent type 'MyProject.Models.Category'. The Name value should be a valid navigation property name."
I also tried this:
public class Category
{
public virtual long CategoryID { get; set; }
[ForeignKey("Category")]
public virtual long? ParentCategoryID { get; set; }
public virtual int UserID { get; set; }
public virtual string Name { get; set; }
}
But again this resulted in the same error.
Is it possible to model this using EF Code First? Its easy to model it int he database if I were to create the database manually.
Thanks in advance
Ben
Your first example wouldn't even compile because T?, a shortcut for Nullable<T> can only be applied to value types.
The following works fine here:
public class Category
{
public virtual long CategoryID { get; set; }
public virtual Category ParentCategory { get; set; }
}
Now, this will use an ugly name by default for the FK, ParentCategory_CategoryID.
This is a way to get a nicer name, plus some flexibility when using it:
public class Category
{
public virtual long CategoryID { get; set; }
[ForeignKey("ParentCategoryID")]
public virtual Category ParentCategory { get; set; }
public virtual long? ParentCategoryID { get; set; }
}
Using EF Code First and given an Entity that contains a List, how can I eagerly load the entire object graph for that entity:
Example:
public class Foo
{
public int Id { get; set; }
public List<BarBase> Bars { get; set; }
}
public class BarBase
{
public int Id { get; set; }
public string Text { get; set; }
}
public class BarTypeA : BarBase
{
public List<Baz> Bazes { get; set; }
}
public class BarTypeB : BarBase
{
public List<Quux> Quuces { get; set; } { get; set; }
}
If BarBase were not a base class that could contain instances of several different subtypes, I could use
.Include("Bars").Include("Bars.Bazes")
If I try
.Include("BarBase").Include("BarBase.Bazes").Include("BarBase.Quuces")
I get the error
A specified Include path is not valid. The EntityType 'BarBase' does
not declare a navigation property with the name 'Bazes'.
But how do I handle the situation that Bars can contain different concrete types, and I want to eagerly load all of those instances including the List<T> contained in those concrete types?
This is reported problem in EF currently without a solution.
I have a domain model:
public class Project
{
[Key]
public int ProjectID { get; set; }
public string Title { get; set; }
public string Slug { get; set; }
public string Content { get; set; }
public string Category { get; set; }
public string Client { get; set; }
public int Year { get; set; }
}
I have a view model (which is a portion of the above model):
public class ListProjectsViewModel
{
public IEnumerable<ProjectStuff> SomeProjects { get; set; }
public class ProjectStuff
{
public int ProjectID { get; set; }
public string Title { get; set; }
public string Slug { get; set; }
public string Content { get; set; }
}
// Some other stuff will come here
}
I have an action controller:
public ActionResult List()
{
// Get a list of projects of type IEnumerable<Project>
var model = m_ProjectBusiness.GetProjects();
// Prepare a view model from the above domain entity
var viewModel = Mapper.Map..........
return View(viewModel);
}
How can I code the mapping '........' with automapper ?
Thanks.
There are two steps.
1) Define a mapping with AutoMapper (this is usually done in some sort of bootstrapper called by Global.asax, etc.)
// since all of your properties in Project match the names of the properties
// in ProjectStuff you don't have to do anything else here
Mapper.CreateMap<Project, ListProjectsViewModel.ProjectStuff>();
2) Map the object in your controller:
// Get a list of projects of type IEnumerable<Project>
var projects = m_ProjectBusiness.GetProjects();
// Prepare a view model from the above domain entity
var viewModel = new ListProjectsViewModel
{
SomeProjects = Mapper.Map<IEnumerable<Project>, IEnumerable<ListProjectsViewModel.ProjectStuff>>(projects)
};
return View(viewModel);
The thing to note here is that you are defining a mapping between Project and ProjectStuff. What you are trying to map is a list of Projects (IEnumerable) to a list of ProjectStuff (IEnumerable). AutoMapper can do this automatically by putting that in the generic arguments as I did above. Your View Model that your view is using is wrapping your list of ProjectStuff, so I just create a new ListProjectsViewModel and do the mapping inside of that.