I'm trying to create a one-to-one relation between two tables, but as a result I have one-to-many. What is the problem with this code?
namespace EFCF_Demo.Models
{
public class Post
{
[Key]
public int ID { get; set; }
public string Title { get; set; }
public string MiniContent { get; set; }
public string Author { get; set; }
public DateTime PublishDate { get; set; }
public int Rating { get; set; }
public virtual Content MainContent { get; set; }
}
public class Content
{
public int ID { get; set; }
public virtual Post Post { get; set; }
public string FullContent { get; set; }
}
public class PostEntities : DbContext
{
public DbSet<Post> Posts { get; set; }
public DbSet<Content> Contents { get; set; }
}
}
Don't you need PostId in the Content class, and ContentId in the Post class?
public class Content
{
[Key]
public int PostId { get; set; }
public virtual Post Post { get; set; }
public string FullContent { get; set; }
}
what about this:) This should do it.
Problem was resolved by removing
public DbSet<Content> Contents { get; set; }
After that we don't need to use the Fluent API but I have some problems with saving.
Try this:
http://social.msdn.microsoft.com/Forums/eu/adonetefx/thread/4b5a46e0-f5c2-4c38-a73c-0038eaef2537
How to declare one to one relationship using Entity Framework 4 Code First (POCO)
Related
I am trying to update an record in my system. Everything on the model saves great, except any of my many to many type relationships on the form. When I get to those in my model it gives me the error. "The member with identity 'PmData.SafetyRequirement_Assets' does not exist in the metadata collection.\r\nParameter name: identity". I've read over some of the other answers but I do not have any triggers on my database, and I've gone through several changes in my model based on other suggestions and it doesn't seem to change anything. The project is in vNext.
Here is my first model
public partial class Asset : DataModel
{
[Required]
[StringLength(64)]
public string Name { get; set; }
[StringLength(256)]
public string Description { get; set; }
[StringLength(1024)]
public string SystemFunction { get; set; }
[StringLength(2048)]
public string Remarks { get; set; }
public bool IsSystem { get; set; }
public bool IsGrouping { get; set; }
[StringLength(128)]
public string FieldTag { get; set; }
[ForeignKey("Parent")]
public int? ParentId { get; set; }
[ForeignKey("Building")]
public int? BuildingId { get; set; }
public bool IsOperable { get; set; }
public bool IsAvailable { get; set; }
public virtual Asset Parent { get; set; }
public virtual Building Building { get; set; }
public virtual ICollection<Asset> Children { get; set; }
public virtual ICollection<DrawingReference> DrawingReferences { get; set; }
public virtual ICollection<SpecReference> SpecReferences { get; set; }
public virtual ICollection<SafetyRequirement> SafetyRequirements { get; set; }
public virtual ICollection<SupportSystem> SupportSystems { get; set; }
}
The model for one the other table with a many to many.
public partial class SafetyRequirement : DataModel
{
[StringLength(256)]
[Required]
public string Name { get; set; }
[StringLength(2048)]
public string SafetyFunction { get; set; }
[StringLength(2048)]
public string FunctionalRequirements { get; set; }
[StringLength(2048)]
public string SystemBoundary { get; set; }
[StringLength(255)]
public string Reference { get; set; }
[ForeignKey("QualityLevel")]
public int QualityLevelId { get; set; }
public virtual QualityLevel QualityLevel { get; set; }
public virtual ICollection<Asset> Assets { get; set; }
}
The map for the joining table
modelBuilder.Entity<Asset>().HasMany(t => t.SafetyRequirements)
.WithMany(t => t.Assets)
.Map(m =>
{
m.MapRightKey("SafetyRequirementId");
m.MapLeftKey("AssetId");
m.ToTable("AssetSafetyRequirement");
});
Finally here's the area that it fails...
public virtual void SaveAsync(TEntity model)
{
Task.Run(() =>
{
using (
var dbContext =
(TContext)
Activator.CreateInstance(typeof (TContext),
ConfigOptions == null ? ConfigService.ConnectionString : ConfigOptions.ConnectionString))
{
var dbSet = dbContext.Set<TEntity>();
dbSet.Attach(model);
dbContext.Entry(model).State = EntityState.Modified;
dbContext.SaveChanges();
}
});
}
Any information or pointers would be greatly appreciated.
You're trying to use both Fluent API and Data Annotations to define the relationships between your tables. Remove one or the other.
Let's take a look at the example from the official docs:
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public BlogImage BlogImage { get; set; }
}
public class BlogImage
{
public int BlogImageId { get; set; }
public byte[] Image { get; set; }
public string Caption { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
}
As we can see, we have fully defined one-to-one relationship between Blog and BlogImage, where Blog is parent, and BlogImage is child entity.
But, if we'll take a look at created tables, we'll see this headers:
BlogId, Url for Blog
BlogImageId, Image, Caption, BlogId for
BlogImage
I have some misunderstood with this BlogId in BlogImage table, shouldn't we have defined the BlogImageId foreign key in Blog table, what's the reason, to define foreign keys in child entiities nor in parent's? If we have thousand parent's of one child, there would be thousand of foreign keys in child entity! Very strange.
Yes, for exact one-to-one relationship you should use this models (your generated tables schemas correspond to one-to-many relationship):
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public virtual BlogImage BlogImage { get; set; }
}
public class BlogImage
{
[Key, ForeignKey("Blog")]
public int BlogImageId { get; set; }
public byte[] Image { get; set; }
public string Caption { get; set; }
public virtual Blog Blog { get; set; }
}
The documentation has just explained the one-to-one relationship in this way but it's not the only way. The way you are thinking is also right. Following is also valid one to one relationship in EF.
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public int BlogImageId { get; set; }
public BlogImage BlogImage { get; set; }
}
public class BlogImage
{
public int BlogImageId { get; set; }
public byte[] Image { get; set; }
public string Caption { get; set; }
public Blog Blog { get; set; }
}
I'm working on a project where the MongoDB model will be similar to Facebook. So we all know how FB works, a user "likes" a band/company page, and that user will see all the posts from that page.
Is the below model how I should design this?
If a Page has million likes, then each Post will have a million sub documents of Like. That does not seem right, there must be a better way that I cant think of.
Thanks.
public class Person
{
public ObjectId Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Page
{
public ObjectId Id { get; set; }
public string Name { get; set; }
public List<Like> PersonLikes { get; set; }
}
public class Like
{
public ObjectId Id { get; set; }
public ObjectId UserId { get; set; }
public DateTime DateLiked { get; set; }
}
public class Post
{
public ObjectId Id { get; set; }
public ObjectId PageId { get; set; }
public string Message { get; set; }
public List<Like> PersonLikes { get; set; }
}
My take assuming you only want to track likes
public class Page
{
public ObjectId Id { get; set; }
public DateTimeOffset Date { get; set; }
public string Name { get; set; }
public int NumberOfLikes { get; set; }
}
public class Post
{
public ObjectId Id { get; set; }
public ObjectId PageId { get; set; }
public DateTimeOffset Date { get; set; }
public string Message { get; set; }
public int NumberOfLikes { get; set; }
}
I would then queue the Reaction (Like or Dislike) for insertion, "sentiment" information doesn't have to be stored in real time, does it? These are not medications, bank transactions, etc.
public class Like
{
public ObjectId Id { get; set; }
public ObjectId ParentId { get; set;}
public ObjectId UserId { get; set; }
public DateTimeOffset Date { get; set; }
}
Queue where? to a collection of Likes. Why not part of the page or post? Because if a post goes viral (as you said even though the majority won't), you may end up with a 1,000,000 likes. Who is going to browse this information other than an analytic engine?
You also have to ensure a user can only express their reaction only once per item.
The post only exists on one page so it´s the page that should own the post, not the post owning the page.
public class Person
{
public ObjectId Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Page
{
public ObjectId Id { get; set; }
public string Name { get; set; }
public List<Like> PersonLikes { get; set; }
public List<Post> Posts { get; set; }
}
public class Post
{
public ObjectId Id { get; set; }
public string Message { get; set; }
public List<Like> Likes { get; set; }
}
public class Like
{
public ObjectId Id { get; set; }
public ObjectId UserId { get; set; }
public DateTime DateLiked { get; set; }
}
I am a VB.NET programmer, but I am trying to learn C# and MVC in my spare time. I am using ASP.NET MVC 5.1.0.0 and I am trying to do code-First database creation in a local instance of SQL Server.
I was able to get the first database table to update in the database when I ran Update-Database from within the IDE, but when I added a second table that has a PK/FK relationship with the first, I am getting a red line under [ForeignKey] which reads
Does not contain a constructor that takes 1 arguments
I have been searching all over and not getting anywhere. Any suggestions or help would be appreciated. By the way, the first table is a PK/FK relationship to the AspNetUsers table.
public class BuildDatabase : IdentityUser
{
public virtual Companies Companies { get; set; }
public virtual NotaryProfile NotaryProfile { get; set; }
}
public class Companies
{
[Key]
[Column("CompanyID")] // Did this as the database will reflect TableName_ColumnName instead.
public int CompanyID { get; set; }
public string CompanyName { get; set; }
public bool IsActive { get; set; }
public bool IsNotary { get; set; }
public virtual ICollection<NotaryProfile> NotaryProfile { get; set; }
}
public class NotaryProfile
{
[Key]
public int NotaryID { get; set; }
public string NamePrefix { get; set; }
public string FirstName { get; set; }
public string MiddleInitial { get; set; }
public string LastName { get; set; }
public string NameSuffix { get; set; }
public bool IsActive { get; set; }
public int DefaultState { get; set; }
public int DefaultCounty { get; set; }
public bool IsSigningAgent { get; set; }
public bool HasABond { get; set; }
public decimal BondAmount { get; set; }
public bool HasEandO { get; set; }
public decimal EandOAmount { get; set; }
public bool ElectronicNotarizationsAllowed { get; set; }
public string ElectronicTechnologyUsed { get; set; }
public string ComissionNumber { get; set; }
public DateTime CommissionIssued { get; set; }
public DateTime CommssionOriginal { get; set; }
public DateTime CommissionExpires { get; set; }
public DateTime CommissionFiledOn { get; set; }
public string SOSAuditNumber { get; set; }
public string CommissionDesc { get; set; }
[Foreignkey("CompanyID")] // Companies.CompanyID = PK
public int CompanyID { get; set; } // PK/FK relationship.
public Companies Companies { get; set; } // Reference to Companies table above.
}
public class SchemaDBContext : IdentityDbContext<BuildDatabase>
{
public SchemaDBContext()
: base("DefaultConnection"){}
public DbSet<Companies> Companies { get; set; }
public DbSet<NotaryProfile> NotaryProfile { get; set; }
}
One of your classes (probably NotaryProfile) needs to reference another object (the foreign key relationship) but there is no constructor in that class that accepts an argument to establish that relationship, e.g.:
public NotaryProfile(int companyId) {
this.companyId = companyId;
}
BTW, a better way to establish that relationship is to use the actual class type rather than the ID, as in:
public class NotaryProfile {
...
public Company Company { get; set; }
// Instead of this:
// public int CompanyID { get; set; } // PK/FK relationship.
...
}
See also:
C# “does not contain a constructor that takes '1' arguments”
Does not contain a constructor that takes 2 arguments
I am trying to create 1-M relationship (1-*) and I cannot make this work.
I have Article model and ArticleTag model. Logically I want to have an article linked with many tags. In "non-model" way, I would make 2 tables according these two models.
public class Article
{
public int ArticleID { get; set; }
public string Title { get; set; }
public DateTime Date { get; set; }
public string Anotation { get; set; }
public string Body { get; set; }
public string SourceLink { get; set; }
public virtual ICollection<ArticleTag> ArticleTags { get; set; }
}
public class ArticleTag
{
public int ArticleID { get; set; } //FK of the Article
public string TagName { get; set; }
}
I have seen only entities with an ID, but here, I wouldn´t think it´s necessary, to every row in ArticleTag table have its own ID. Isn´t it?
How should I write it down? Thx a lot.
First of all, you need to have a unique Id for both ArticleTag and Article. Then you need to insert ArticleID into Article Tag, because the entity needs to know which ArticleTags belong to an Article. Simplified, this is how it should look:
public class Article
{
public int ArticleID { get; set; }
public string Title { get; set; }
public DateTime Date { get; set; }
public string Anotation { get; set; }
}
public class ArticleTag
{
public int ArticleTagID { get; set; }
public int ArticleID { get; set; } //This creates the link 1-M
public string TagName { get; set; }
}