Academic Example: Simple Tagging Mechanism - asp.net / MVC5
Models:
// post
public class Post
{
public Int64 Id { get; set; }
public string Title { get; set; }
public virtual IList<TagMap> TagMaps { get; set; }
}
// tag
public class Tag
{
public Int64 Id { get; set; }
public string Name { get; set; }
public virtual Post Post { get; set; }
}
// tagmap
public class TagMap
{
public Int64 Id { get; set; }
public virtual Post Post { get; set; }
public virtual Tag Tag { get; set; }
}
The TagTable contains single tagwords (no duplicates). TagMap represents the relationship between the Post and (many) Tags.
I think this simple design should work or not? But I don't know how to setup the views for editing and creating the tags (not the tagmaps).
Any help would be nice.
It seems that you are achieving a one-to-many relationship. (one post, many tags)..
You can have it with this..
public class Post
{
[Key]
public Int64 PostId { get; set; }
public string Title { get; set; }
}
public class Tag
{
[Key]
public Int64 TagId { get; set; }
public string Name { get; set; }
}
public class TagMap
{
public Int64 PostId { get; set; }
public Int64 TagId { get; set; }
[ForiegnKey("PostId")]
public virtual Post Post { get; set; }
[ForiegnKey("TagId")]
public virtual Tag Tag { get; set; }
}
Take note that you do not need lazy loading on two tables since that you actually referenced it to tagmap table.
Ok sounds nice.
I changed the model to:
public class Post
{
[Key]
public Int64 Id { get; set; }
public string Title { get; set; }
public IList<TagMap> TagMaps { get; set; }
}
In the index method of the postscontroller:
var posts = db.Posts.Include(m => m.TagMaps.Select(n => n.Tag));
And the view:
#for (int i = 0; i < item.TagMaps.Count; i++)
{
#Html.Raw(item.TagMaps[i].Tag.Name);
}
This is working like a charme.
Related
I have domain model like this
public class EntityOne
{
public int EnityOneId { get; set; }
public int EntityOnePropertyOne { get; set; }
public List<EntityTwo> EntityTwos { get; set; }
}
public class EntityTwo
{
public int EntityTwoId { get; set; }
public string EntityTwoPropertyOne { get; set; }
public int EntityThreeId { get; set; }
public int EnityOneId { get; set; }
public virtual EntityOne EntityOne { get; set; }
public virtual EntityThree EntityThree { get; set; }
}
public class EntityThree
{
public int EntityThreeId { get; set; }
public string EntityThreePropertyOne { get; set; }
}
and I have DTO like this
public class EntityDTO
{
public int EntityOnePropertyOne { get; set; }
public string EntityThreePropertyOne_ValueOne { get; set; }
public string EntityThreePropertyOne_ValueTwo { get; set; }
public string EntityThreePropertyOne_ValueThree { get; set; }
public string EntityThreePropertyOne_ValueFour { get; set; }
public string EntityThreePropertyOne_ValueFive { get; set; }
}
I want to configure mapping from DTO to DomainModel and the reverse using AutoMapper but I didnt know how to do that... any suggestion or help
I'm not sure what you're trying to accomplish here.
I get that you want to map to EntityDTO, but from what other type? I will assume you want to use EntityTwo as the source.
In that case,
EntityOnePropertyOne: Will be obtained automatically via Flattening from the source (EntityTwo) - So, no problem here.
EntityThreePropertyOne_ValueOne: This will assume you have a property called EntityThree (which you do), and within that type, a property called PropertyOne_ValueOne of type int (which you don't). Same applies for the rest.
The other way around will get trickier, since I see there will be lots of properties ignored, so you need to tell AutoMapper, that you don't want it to be concerned about all that bunch of properties in your complex type, that don't come from the DTO.
I have an Exercise entity defined in my ASP.NET MVC4 Web Application.
I'm using the Form Authentication with the default AccountModels.cs class.
I have class which looks like
public class Exercise
{
private DateTime _DateCreated = DateTime.Now;
private UserProfile _Teacher;
public int Id{ get; set; }
public string Question { get; set; }
public int Anwser { get; set; }
public string Category { get; set; }
public int maxNbrOfAttempts { get; set; }
public string Hints { get; set; }
public virtual ICollection<Quiz> Quizzes { get; set; }
public DateTime Date
{
get { return _DateCreated; }
set { _DateCreated = value; }
}
public UserProfile Author
{
get { return _Teacher; }
set { _Teacher = value; }
}
}
Am I using the UserProfile correctly to link between an Exercise and a logged in user?
How can I get the current UserProfile in my controller?
Change it like this:
public class Exercise
{
public Exercise()
{
this.Date = DateTime.Now;
this.Author = User.Identity.Name; //Write this line if you want to set
//the currently logged in user as the Author
public int Id{ get; set; }
public string Question { get; set; }
public int Anwser { get; set; }
public string Category { get; set; }
public int maxNbrOfAttempts { get; set; }
public string Hints { get; set; }
public virtual ICollection<Quiz> Quizzes { get; set; }
public virtual DateTime Date { get; set; }
public virtual UserProfile Author { get; set; }
}
I'm new to mvc. I've creted an MVC app, in which i have used code first approach. Right now i have two tables Deal and Comment. Now i want to add a new table Category in the database and new column categoryId in Deal table.
How i can update database and model?
I'm using Sql Server 2008 R2 for Database.
I've following structure of class:
namespace FBWebApp.Models
{
public class Deal
{
public int ID { get; set; } // ID
public string Title { get; set; } // Titolo del deal
public string Description { get; set; } // Descrizione dell'annuncio
public string FacebookUID { get; set; } // UID facebook dell'utente
public string Visibility { get; set; } // Visibility
public string Category { get; set; }
public int Option1 { get; set; }
public int Option2 { get; set; }
public int Option3 { get; set; }
public int Option4 { get; set; }
public string PhotoURL { get; set; } // URL of the facebook photo profile
public string Name { get; set; } // Name of the user
public string ProfileUrl { get; set; } // URL of the facebook profile
public string Photo1 { get; set; } // URL of the Photo1 (local )
public string Photo2 { get; set; }
public string Photo3 { get; set; }
public string Photo4 { get; set; }
public string Photo5 { get; set; }
}
public class Comment
{
[Key]
public int CommentId { get; set; }
public string CommentText { get; set; }
public int ID { get; set; }
[ForeignKey("ID")]
public Deal DelNav { get; set; }
}
public class DealDBContext : DbContext
{
public DealDBContext() : base("DealDBContext") { }
public DbSet<Deal> Deals { get; set; }
public DbSet<Comment> Comments { get; set; }
}
}
Try using 'update-database -force -verbose' in the Package Manager Console.
If it doesn't work, modify the migration but typing 'add-migration somename' and it will apear in the Migrations folder.
If you are new to MVC and EF, definitely check out this tutorial. It explains all about that and everything else you need to know:
http://pluralsight.com/training/Player?author=scott-allen&name=mvc4-building-m1-intro&mode=live&clip=0&course=mvc4-building
first add your model :
public class Category
{
public int ID { get; set; }
public int cateName { get; set; }
}
in Deal class :
public class Deal
{
//..
[ForeignKey("CatId")]
public virtual Category Category { get; set; }
}
after Enable Migration you should use this command in console manager to update your database :
update-database
Could someone show me how to create a relationship in my EF codefirst example - I want a relationship on the Products class that has a many relationship to the Product_Spec class so when I compile the code it will have relationships when the database is generated, and also a relationship for the Specification class related to the Product_Spec
Data Context class
classes:
namespace MvcApplication1.Models
{
public class Department
{
[Key]
public long Id { get; set; }
[Required(ErrorMessage="Please enter a name for the departments.")]
[DataType(DataType.Text)]
public string Name { get; set; }
[DataType(DataType.Text)]
[Required(ErrorMessage = "Please enter a valid url for the department.")]
public string Url { get; set; }
public virtual List<Product> Products { get; set; }
}
public class Product
{
[Key]
public long Id { get; set; }
[ForeignKey("FK_Department_Id")]
public long DepartmentId { get; set; }
[DataType(DataType.Text)]
public string Title { get; set; }
[DataType(DataType.Currency)]
public decimal UnitPrice { get; set; }
[DataType(DataType.Currency)]
public decimal SellPrice { get; set; }
}
public class Product_Spec
{
[ForeignKey("FK_Spec_ProductId")]
public long ProductId { get; set; }
[ForeignKey("FK_Spec_SpecId")]
public long SpecId { get; set; }
}
public class Specification
{
[Key]
public long SpecId { get; set; }
[DataType(DataType.Text)]
[Required(ErrorMessage = "Please enter a product specification type.")]
public string Type { get; set; }
[DataType(DataType.Text)]
[Required(ErrorMessage = "Please enter a product specification value.")]
public string Value { get; set; }
}
}
namespace MvcApplication1
{
public class DataContext : DbContext
{
public DbSet<Department> Department { get; set; }
public DbSet<Product> Product { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Department>().HasRequired(x => x.Products)
.WithMany().HasForeignKey(x => x.Id).WillCascadeOnDelete(true);
modelBuilder.Entity<Product>().HasOptional(x => x.Product_Specs)
.WithMany().HasForeignKey(x =>x.ProductId) // this lines doesn't work
base.OnModelCreating(modelBuilder);
}
}
}
I think you should set column names in ForeignKey attribute, not constraint names:
public class Product
{
[Key]
public long Id { get; set; }
public long DepartmentId { get; set; }
[DataType(DataType.Text)]
public string Title { get; set; }
[DataType(DataType.Currency)]
public decimal UnitPrice { get; set; }
[DataType(DataType.Currency)]
public decimal SellPrice { get; set; }
[ForeignKey("DepartmentId")]
public virtual Department Department { get; set; }
public ICollection<Product_Spec> ProductSpecs { get; set; }
}
public class Product_Spec
{
public long ProductId { get; set; }
public long SpecId { get; set; }
[ForeignKey("ProductId")]
public virtual Product Product {get; set;}
}
It looks like you're trying to create a Many-Many relationship between Products and Specifications. If that's the case, you don't need to define Product_Spec, using the default conventions, Entity Framework will create your required junction table for you provided you make some alterations to your entities (to define the relationship).
In your case, you could make the following alterations:
public class Product
{
// Your other code
// [ForeignKey("FK_Department_Id")] - Not required, EF will configure the key using conventions
public long DepartmentId { get; set; }
public virtual ICollection<Specification> Specifications { get; set; } // Navigation property for one end for your Product *..* Specification relationship.
}
public class Specification
{
// Your other code
public virtual ICollection<Product> Products { get; set; }
}
When your tables are created, you should see a table with a name like SpecificationProducts, which is the junction table used to hold your many..many Product/Specification relationship.
If you needed to explicitly define this mapping (for example if you had an existing tables), you should be able to do something like this:
modelBuilder.Entity<Product>().
HasMany(s => s.Specifications).
WithMany(p => p.Products).
Map(
m =>
{
m.MapLeftKey("ProductId");
m.MapRightKey("SpecId");
m.ToTable("SpecificationProducts");
});
How do I model the following using Castle ActiveRecord?
I have two classes, Customer and Task.
I would like to reuse a third class, Note, stored in a Collection in each of the Customer and Task classes.
public class Note
{
public int ID { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
}
public class Customer
{
public int ID { get; set; }
public IList<Note> Notes { get; set; }
}
public class Task
{
public int ID { get; set; }
public IList<Note> Notes { get; set; }
}
I would then like to be able to pass the Notes collection to a Gridview, Listview or Repeater in the relevant ASP.Net page for the Customer or Task classes.
I think what you need is to implement a type hierarchy. You can read about it here.
We settled on the following pattern:
[ActiveRecord]
public class Note
{
[PrimaryKey]
public int ID { get; set; }
[Property]
public string Subject { get; set; }
[Property]
public string Body { get; set; }
[BelongsTo]
public Customer Customer { get; set; }
[BelongsTo]
public Customer Task{ get; set; }
}
[ActiveRecord]
public class Customer
{
[PrimaryKey]
public int ID { get; set; }
[HasMany]
public IList<Note> Notes { get; set; }
}
[ActiveRecord]
public class Task
{
[PrimaryKey]
public int ID { get; set; }
[HasMany]
public IList<Note> Notes { get; set; }
}