Mapping self-referencing table data into another model (no automapper is used) - c#

I have this table using Entity Framework code first approach :
public class WebsitePart
{
public WebsitePart()
{
SubParts = new HashSet<WebsitePart>();
}
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public Nullable<int> ParentId { get; set; }
[StringLength(100)]
[Index("UQ_WebsitePart_Key", IsUnique = true)]
public string Key { get; set; }
public virtual WebsitePart Parent { get; set; }
public virtual ICollection<WebsitePart> SubParts { get; set; }
}
I need after getting the list of WebsiteParts to map it into List of another model where each element of this list has ParentId=null and down to the end of its grandsons(traversing) .
This the model I want to map to:
public class WebPartViewDto
{
public int Id { get; set; }
public string Key { get; set; }
public IList<WebPartViewDto> SubWebParts { get; set; }
}
Could you please show me how to map it with performance is taken into account?

Related

How to Add related entites to database using EntityFramework

I am trying add the cart to database but don't know how to add related Entities
My related tables are ( carts , products , productoptions , options)
How Can I add or Update those tables at the same time? And how can I set Foreign keys to related Tables
thanks...
You will create models for each of your tables (see below)
Then if you add just a child you will have to add it with the foreig nkey property populated
var test = childObj { parentPropertyId = parentPropertyIdValue}
If you add parent and child together you can just add and entity mework will take care of that. For example:
var test = new parentObj {
someProperty = someValue,
childProperty = new childObj{
//here will not have to populate the parentPropertyId
}
}
See sample models for your above tables
Use the [Key] attribute to specify your primary key
Use the [ForeignKey] attribute above your related entity property to specify which property to use as foreign key
Use an ICollection to access the children of an object
public class Carts
{
[Key]
public int Id { get; set; }
public int Userid { get; set; }
public DateTime CreatedDate { get; set; }
public ICollection<Products> Products { get; set; }
}
public class Products
{
[Key]
public int Id { get; set; }
public string SerialNumber { get; set; }
public string StockCode { get; set; }
public int CartId { get; set; }
public int Quantity { get; set; }
[ForeignKey(nameof(CartId))]
public Carts Cart { get; set; }
}
public class ProductOptions
{
[Key]
public int Id { get; set; }
public int ProductId { get; set; }
public int OptionId { get; set; }
[ForeignKey(nameof(ProductId))]
public Products Products { get; set; }
[ForeignKey(nameof(OptionId))]
public Options Options { get; set; }
}
public class Options
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public int Quantity { get; set; }
public int ParentId { get; set; }
public int GrandParentId { get; set; }
}

InCorrect Map In AutoMapper When Map Model To ViewModel

I Have an Model"TClientsAdmins" and ViewModel is TClientsAdminsViewModel.I want read all records from DB where filtered by id.
I Read they from domain model and when I want Map to viewmodel I get zero Count in viewmodel.
In addition I have a model that is called THoldingAdmins That is associated with TClientsAdmins.
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public int Id { get; set; }
[StringLength(50)]
public string CompanyName { get; set; }
public int? THoldingAdminsId { get; set; }
public virtual THoldingAdmins THoldingAdmins { get; set; }
and TClientAdminViewModel :
public int Id { get; set; }
[StringLength(50)]
public string CompanyName { get; set; }
public int? THoldingAdminsId { get; set; }
public virtual THoldingAdminsViewModel THoldingAdmins { get; set; }
and THoldingAdmins:
public byte[] Logo { get; set; }
public bool IsDeleted { get; set; }
public virtual List< TClientsAdmins> TClientsAdmins { get; set; }
and AutoMapper Configuration :
Mapper.CreateMap<TClientsAdminsViewModel, TClientsAdmins>();
Mapper.CreateMap<List<TClientsAdminsViewModel>,List<TClientsAdmins>>();
You don't need an explicit mapping for IList, but it does look like you have your mapping the wrong way round, if you're mapping from Model to ViewModel. Try
Mapper.CreateMap<TClientAdmins, TClientAdminsViewModel>();
Mapper.CreateMap<THoldingAdmins, THoldingAdminsViewModel>();

How to create a foreign relation to one Model from multiple other models using Entity framework?

I am trying to create my first app using ASP.NET MVC framework and Entity Framework 6.
I chose to use code first approach and I started by defining my Models.
I have a model called Client with an identity attribute called Id. I have multiple Models that has an attribute called ClientId. The ClientId attribute should have virtual link to the Clients Model.
Here is how my Client model looks like
[Table("clients")]
public class Client
{
[Key]
public int id { get; set; }
public string name { get; set; }
public string status { get; set; }
public DateTime created_at { get; set; }
public DateTime? modified_at { get; set; }
public Client()
{
status = "Active";
created_at = DateTime.UtcNow;
}
}
Then here is how I am creating a belong to relation using other models.
[Table("BaseClientsToUsers")]
public class ClientToUser : ModelDefault
{
[ForeignKey("User")]
public int UserID { get; set; }
[ForeignKey("Client")]
public int ClientId { get; set; }
[ForeignKey("Team")]
public int DefaultTeamId { get; set; }
public DateTime? JoinedAt { get; set; }
public bool IsActive { get; set; }
public virtual User User { get; set; }
public virtual Client Client { get; set; }
public virtual Team Team { get; set; }
public ClientToUser()
{
DateTime UtcNow = DateTime.UtcNow;
IsActive = true;
CreatedAt = UtcNow;
LastUpdatedAt = UtcNow;
}
[Table("BaseTeams")]
public class Team : ModelDefault
{
[MaxLength(250)]
public string Name { get; set; }
[ForeignKey("Client")]
public int ClientId { get; set; }
public bool IsActive { get; set; }
public virtual Client Client { get; set; }
public Team()
{
DateTime UtcNow = DateTime.UtcNow;
IsActive = true;
CreatedAt = UtcNow;
LastUpdatedAt = UtcNow;
}
}
But, when I try to update my databases I get the following error
Introducing FOREIGN KEY constraint
'FK_dbo.BaseTeams_dbo.BaseClients_ClientId' on table 'BaseTeams' may
cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or
ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. Could
not create constraint or index. See previous errors.
I am not really sure what could be causing the error but it seems it is because I am creating multiple Foreign keys to the same `Clients model.
How can I fix this error?
Hello #Mike A When I started MVC I got this error too, so you need aditional tables that connects your DB items.
So try connect your database items with tables like that:
Here is my working example:
[Table("Products")]
public class Product
{
[Key]
public string Id { get; set; }
[Required]
public string Name { get; set; }
public string Description { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
public decimal InternalPrice { get; set; }
public string Url { get; set; }
}
[Table("Categories")]
public class Category
{
[Key]
public string Id { get; set; }
[Required]
public string Name { get; set; }
public string Url { get; set; }
}
[Table("ProductCategories")]
public class ProductCategory
{
[Key]
[Column(Order = 0)]
public string ProductId { get; set; }
[Key]
[Column(Order = 1)]
public string CategoryId { get; set; }
public virtual Category Category { get; set; }
}
So you can connect your items without problems hope this will help you.

Create relation code First Entity Framework

I have a model:
public class Delivery
{
public Guid Id { get; set; }
public string Name { get; set; }
public Guid BusinessId { get; set; }
public virtual ICollection<PriceDisc> PriceDisc { get; set; }
}
public class PriceDisc
{
public Guid Id { get; set; }
public decimal Amount { get; set; }
public Guid BusinessId { get; set; }
}
How to create relation one to many between Delivery.BusinessId and PriceDisc.BuissnessId?
Thanks
you have already created a one to many relationship between them Delivery hold collection of PriceDisc in your code so for one Delivery.BusinessId you have collection of PriceDisc.BusinessId

Relationships in Entity Framework Code First

yesterday I created database in Management Studio and now I want to create it in program using EF Code First.
Here is link to my database: http://s11.postimg.org/6sv6cucgj/1462037_646961388683482_1557326399_n.jpg
And what I did:
public class GameModel
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public DateTime CreationTime { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string TotalTime { get; set; }
public DateTime RouteStartTime { get; set; }
public DateTime RouteEndTime { get; set; }
public int MaxPlayersPerTeam { get; set; }
public int CityId { get; set; }
public int CreatorId { get; set; }
[InverseProperty("Id")]
[ForeignKey("CreatorId")]
//public int TeamId { get; set; }
//[ForeignKey("TeamId")]
public virtual UserModel Creator { get; set; }
public virtual CityModel City { get; set; }
//public virtual TeamModel WinnerTeam { get; set; }
}
public class RegionModel
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<CityModel> Cities { get; set; }
}
public class CityModel
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public int RegionId { get; set; }
public virtual RegionModel Region { get; set; }
public virtual ICollection<UserModel> Users { get; set; }
public virtual ICollection<GameModel> Games { get; set; }
}
public class UserModel
{
[Key]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Login { get; set; }
public string Password { get; set; }
public string Email { get; set; }
public DateTime RegistrationDate { get; set; }
public string FacebookId { get; set; }
public int CityId { get; set; }
public virtual CityModel City { get; set; }
public virtual IEnumerable<GameModel> Games { get; set; }
}
For now I wanted to create 4 tables but I have some problems... I want to make CreatorId in GameModel, but it doesn't work... When i wrote UserId instead of CreatorId it was working ( without [InverseProperty("Id")] and [ForeignKey("CreatorId")]).
This is what i get:
The view 'The property 'Id' cannot be configured as a navigation property. The property must be a valid entity type and the property should have a non-abstract getter and setter. For collection properties the type must implement ICollection where T is a valid entity type.' or its master was not found or no view engine supports the searched locations.
edit:
I changed it like this:
public int CityId { get; set; }
public int CreatorId { get; set; }
[ForeignKey("CityId")]
public virtual CityModel City { get; set; }
[ForeignKey("CreatorId")]
public virtual UserModel Creator { get; set; }
And there is another problem.
The view 'Introducing FOREIGN KEY constraint 'FK_dbo.UserModels_dbo.CityModels_CityId' on table 'UserModels' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint. See previous errors.' or its master was not found or no view engine supports the searched locations.
And I have no idea how to solve it.
The InversePropertyAttribute specifies, which navigation property should be used for that relation.
A navigation property must be of an entity type (the types declared in your model, GameModel for example) or some type implementing ICollection<T>, where T has to be an entity type. UserModel.Id is an int, which clearly doesn't satisfy that condition.
So, the inverse property of GameModel.Creator could be UserModel.Games if you changed the type to ICollection<GameModel>, or had to be left unspecified. If you don't specify an inverse property, EF will try to work everything out on its own (in this case it would properly recognize GameModel.Creator as a navigation property, but UserModel.Games would most likely throw an exception, as it is neither an entity type, nor does it implement ICollection<T> with T being an entity type, nor is it a primitive type from a database point of view). However, EF's work-everything-out-by-itself-magic doesn't cope too well with multiple relations between the same entity types, which is when the InversePropertyAttribute is needed.
A quick example that demonstrates the problem:
class SomePrettyImportantStuff {
[Key]
public int ID { get; set; }
public int OtherId1 { get; set; }
public int OtherId2 { get; set; }
[ForeignKey("OtherId1")]
public virtual OtherImportantStuff Nav1 { get; set; }
[ForeignKey("OtherId2")]
public virtual OtherImportantStuff Nav2 { get; set; }
}
class OtherImportantStuff {
[Key]
public int ID { get; set; }
public virtual ICollection<SomePrettyImportantStuff> SoldStuff { get; set; }
public virtual ICollection<SomePrettyImportantStuff> BoughtStuff { get; set; }
}
Here, EF knows that it has to generate 2 FKs from SomePrettyImportantStuff to OtherImportantStuff with the names Id1 and Id2, but it has no way to tell which of the IDs refers to the entity where it was sold from and which is the one it was bought from.
Edit: How to fix the cyclic reference problem
To fix that problem, your context class should override OnModelCreating and configure the foreign keys which shouldn't cascade on delete accordingly, like this:
protected override void OnModelCreating(DbModelBuilder builder)
{
builder.Entity<CityModel>().HasMany(c => c.Users).WithRequired(u => u.City)
.HasForeignKey(u => u.CityId).WillCascadeOnDelete(value: false);
// Add other non-cascading FK declarations here
base.OnModelCreating(builder);
}

Categories

Resources