Entity Framework 6 + One-To One - asp.net-mvc

my Entities are as follows:
public partial class Employee :Person, IEntity<long>
{
.......
public long Salutation_Id { get; set; }
[Required]
[ForeignKey("Salutation_Id")]
public Salutation Salutation { get; set; }
}
public partial class Salutation:BaseEntity,IEntity<long>
{
public long Id { get; set; }
public string SalutationShort { get; set; }
public string SalutationLong { get; set; }
public string LetterSalutation { get; set; }
}
I'm looking for a way to convert this mapping to FluentAPI.
Any Ideas?

Something like...
modelBuilder.Entity<Employee>().HasRequired(e => e.Salutation).WithRequiredDependent().Map(ca => ca.MapKey(new string[] {"Salutation_Id"});
Of course, modelBuilder is an object of type DbModelBuilder, like what you would see when you override the OnModelCreating method of DbContext.

Related

Metadata class not working in Entity Framework? Ignoring class property

I am trying to ignore a class property when inserting data to database using metadata for the class but it is not working. I am using using EF 6. I have tried both the metadata and partial class are in the same assembly as the classes generated by EF
[NotMapped] and [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
Used a internal sealed class (for metadata) inside my partial class
namespace XeroDataStore.XeroDatabase
{
[MetadataType(typeof(TempAddressMetadata))]
public partial class TempAddress
{
}
[MetadataType(typeof(TempContact.TempContactMetadata))]
public partial class TempContact
{
internal sealed class TempContactMetadata
{
[NotMapped]
public Nullable<System.DateTime> UploadDate { get; set; }
}
}
}
namespace XeroDataStore.XeroDatabase
{
public class TempAddressMetadata
{
[NotMapped]
public Nullable<System.DateTime> UploadDate { get; set; }
}
}
EF Generated Class
namespace XeroDataStore.XeroDatabase
{
public partial class TempAddress
{
public int RowId { get; set; }
public int ClientID { get; set; }
public System.Guid ContactID { get; set; }
public string AddressType { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressLine3 { get; set; }
public string AddressLine4 { get; set; }
public string City { get; set; }
public string Region { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
public string AttentionTo { get; set; }
public Nullable<System.DateTime> UploadDate { get; set; }
public virtual TempContact TempContact { get; set; }
}
}
What am I missing here?
Do it using Fluent API to make sure your model classes are POCO and have nothing to do with the data access.
In your data context, OnModelCreating methoed, use the following code to ignore the property
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<TempContact>().Ignore(a => a.UploadDate );
}

Fluent API One to Many mapping table

It's really helpful if anyone could explain me how to create a mapping (associated)table for one to many relationship using Fluent API.`
public class Category
{
public int ID { get; set; }
public string Name { get; set; }
public List<Image> Images { get; set; }
}
public class Image
{
public int ID { get; set; }
public string Name { get; set; }
public List<Category> Category{ get; set; }
The mapping table should contain CategoryID and ImageID.
The solution should be something similar to this. (This is for many to many)
modelBuilder.Entity<Category>()
.HasMany(c => c.Images).WithMany(i => i.Categories)
.Map(t => t.MapLeftKey("CategoryID")
.MapRightKey("ImageID")
.ToTable("CategoryImage"));
I want Fluent API to create new mapping table for the below relationship.
public class Category
{
public List<Image> Images{get; set;}
}
public class Image
{
public Category Category{ get; set; }
}
Adding NewTable:
modelBuilder
.Entity<NewTable>()
.HasRequired(_ => _.Category)
.WithMany()
.HasForeignKey(_ => _.CategoryId);
modelBuilder
.Entity<Image>()
.HasRequired(_ => _.NewTable)
.WithMany(_ => _.Images)
.HasForeignKey(_ => _.NewTableId)
public class NewTable
{
public int ID { get; set; }
public int CategoryId { get; set; }
public List<Image> Images { get; set; }
public virtual Category Category { get; set; }
}
public class Image
{
public int ID { get; set; }
public string Name { get; set; }
public List<Category> Categories { get; set; }
public int NewTableId { get; set; }
public virtual NewTable NewTable { get; set; }
}

Asp.Net MVC Codefirst Model Relation to the Same Model

I have a model and i want to put an extra field which can be populated form the same model. IE: Categories and and sub-categories.
In my example, visitor can add an filetype but if file type is under an another file type, he can choose,
But i cant work it out. Below you can see my model.
public class HrFileType
{
[Key]
public int Id { get; set; }
[Display(Name = "Dosya Adı")]
public int Name { get; set; }
public int? HrFileTypeId { get; set; }
public virtual HrFileType HrFileType2 { get; set; }
}
You just need to add a ForeignKeyAttribute like below:
public class HrFileType
{
[Key]
public int Id { get; set; }
[Display(Name = "Dosya Adı")]
public int Name { get; set; }
public int? HrFileTypeId { get; set; }
[ForeignKey("HrFileTypeId")]
public virtual HrFileType HrFileType2 { get; set; }
}
You can also use fluent API to achieve this:
public class HrFileType
{
[Key]
public int Id { get; set; }
[Display(Name = "Dosya Adı")]
public int Name { get; set; }
public int? HrFileTypeId { get; set; }
public virtual HrFileType HrFileType2 { get; set; }
}
public class YourDbContext : DbContext
{
public DbSet<HrFileType> HrFileTypes { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//
modelBuilder.Entity<HrFileType>()
.HasOptional(c => c.HrFileType2)
.WithMany()
.HasForeignKey(c => c.HrFileTypeId);
}
}
Have you tried listing the other file types?
public class HrFileType
{
[Key]
public int Id { get; set; }
[Display(Name = "Dosya Adı")]
public int Name { get; set; }
public List<HrFileType> RelatedTypes { get; set; }
}
then using Entity Frameworks fluent API in the DbContext, try explicitly declaring a many to many map.
modelbuilder.Entity<HrFileType>().HasMany(x => x.RelatedTypes).WithMany();
I'd be very interested to see if this works. It's the only logical solution I can think of without having some kind of parent class.

Join two model to present in a view in MVC

I want to join two below model class with entity framework in controller for present factor in accounting system in a view
<pre>
namespace AccountingSystem.Models
{
public class BuyFactor
{
public int BuyFactorId { get; set; }
public DateTime CreateDate { get; set; }
public string Seller { get; set; }
public string Creator { get; set; }
public decimal SumAllPrice { get; set; }
public ICollection<BuyFactorDetail> BuyFactorDetails { get; set; }
}
}
namespace AccountingSystem.Models
{
public class BuyFactorDetail
{
public int BuyFactorDetailId { get; set; }
public int Number { get; set; }
public string Description { get; set; }
public decimal SumPrice { get; set; }
public int BuyFactorId { get; set; }
public virtual BuyFactor BuyFactor { get; set; }
public virtual Commodity Commodity { get; set; }
}
}
</pre>
Create a new Model
public class JointModel
{
public BuyFactor BuyFactor {get; set;}
public BuyFactorDetail BuyFactorDetail {get; set;}
}
Just create another model then calls the other model in there
public class ParentModel
{
public BuyFactor BuyFactor {get; set;}
public BuyFactorDetail BuyFactorDetail {get; set;}
}
So when you will call it in view
#model IEnumerable<AccountingSystem.Models.ParentModel>
#Html.DisplayNameFor(model => model.BuyFactor.Creator)
Best way define Model as a Property in Main Model
For example
public class BuyFactor
{
public int BuyFactorId { get; set; }
public DateTime CreateDate { get; set; }
public string Seller { get; set; }
public string Creator { get; set; }
public decimal SumAllPrice { get; set; }
public ICollection<BuyFactorDetail> BuyFactorDetails { get; set; }
public BuyFactorDetail BuyFactorEntity {get;set;}
}
Assign value in BuyFactorEntity and use as Model.BuyFactorEntity.BuyFactorDetailId
Use a Linq join query like
var query = (from b in context.BuyFactors
join d in context.BuyFactorDetail
on
..
select new
{
BuyFactorId = b.BuyFactorId,
....
BuyFactorDetailId = d.BuyFactorDetailId,
...
..
}));
Your BuyFactor already contains the BuyFactorDetail collection. You sure the entities are 1:N relationship with each other?
You can use the BuyFactor as model and could use the BuyFactorDetails propertu of the BuyFactor entity.
Use ViewBag in controller to assign respective objects for both.
ViewBag.BuyFactor= BuyFactor;
ViewBab.BuyFactorDetail = BuyFactorDetail;
To use it in view you will have to typecast them back.

EF4 - Can a POCO be used as both an Entity and ComplexType?

I am using EF4 CTP5. Here are my POCOs:
public class Address
{
public int Id { get; set; }
public string Name { get; set; }
public string Line1 { get; set; }
public string Line2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
}
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public List<Address> Addresses { get; set; }
public List<Order> Orders { get; set; }
}
public class Order
{
public int Id { get; set; }
public decimal Total { get; set; }
public Address ShippingAddress { get; set; }
public Address BillingAddress { get; set; }
}
Is there a way to get Address to be a ComplexType for the Order class? After playing around with this, I'm guessing not, but maybe there's a way I haven't seen.
EDIT: In response to Shawn below, I gave it my best shot:
//modelBuilder.Entity<Order>().Ignore(o => o.BillingAddress);
//modelBuilder.Entity<Order>().Ignore(o => o.ShippingAddress);
modelBuilder.Entity<Order>()
.Property(o => o.BillingAddress.City).HasColumnName("BillingCity");
Fails at runtime with error "The configured property 'BillingAddress' is not a declared property on the entity 'Order'." Trying to use Ignore() doesn't work. Next, the Hanselman article is CTP4, but the CTP5 equivalent is:
modelBuilder.Entity<Order>().Map(mapconfig =>
{
mapconfig.Properties(o => new {
o.Id
, o.Total
, o.BillingAddress.City
});
mapconfig.ToTable("Orders");
});
Fails with error "Property 'BillingAddress.City' of type 'Order' cannot be included in its mapping."
I give up. Maybe the final release will have something like this. Or maybe I need to switch to NHibernate =)
All you need to do is to place ComplexTypeAttribute on Address class:
[ComplexType]
public class Address
{
public int Id { get; set; }
public string Name { get; set; }
public string Line1 { get; set; }
public string Line2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
}
Alternatively, you can achieve this by fluent API:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ComplexType<Address>();
}
But you cannot have Address type as to be both an Entity and a Complex Type, it's one way or another.
Take a look at this blog post where I discuss this at length:
Associations in EF Code First CTP5: Part 1 – Complex Types
If you want Address to be in the same table as Order, you're going to have to tell EF that in the DbContext OnModelCreating override.
Take a look here: http://weblogs.asp.net/scottgu/archive/2010/07/23/entity-framework-4-code-first-custom-database-schema-mapping.aspx

Resources