cannot share table no matching primary key - asp.net

The entity types 'Profile' and 'Country' cannot share table 'Countries' because they are not in the same type hierarchy or do not have a valid one to one foreign key relationship with matching primary keys between them.

try removing
public int? CountryID { get; set; }
from UserProfile so it looks like this:
public class UserProfile
{
[Key]
public int UserID { get; set; }
public virtual Country Country { get; set; }
}
public class Country
{
public Country()
{
Profiles = new HashSet<UserProfile>();
}
[Key]
public int CountryID { get; set; }
public ICollection<UserProfile> Profiles { get; set; }
}
another thing : you had ICollection<Profile> instead of ICollection<UserProfile>

Related

How to retrieve book related to a specific tag

I have 3 tables (User, Tags, Book).
In the User table I have an attribute Interesting, it has a tag_id (I saving inside it a tagid). I also have a Tags table that has many tags with many to many to book table relation.
public class Tag
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string UrlSlug { get; set; }
public virtual string Description { get; set; }
public virtual ICollection<Book> Books { get; set; }
}
and here is the book table :
public partial class Book
{
[Key]
public int Book_id { get; set; }
[Required]
[Display(Name ="User Name")]
[StringLength(128)]
public string User_ID { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
public virtual AspNetUser AspNetUser { get; set; }
}
and here is the user table :
public partial class AspNetUser
{
public string Id { get; set; }
public string Email { get; set; }
public bool EmailConfirmed { get; set; }
public string PasswordHash { get; set; }
[Display(Name = "Interesting")]
public int Interesting { get; set; }
public virtual ICollection<Book> Books { get; set; }
}
What is the SQL statement here to retrieve the book that match the Interesting attribute?
For example in Interesting attribute I have 17 , so I want to retrieve the book that related to the tag id 17 ..
Note: my many-to-many table generated from the relation name is TagBooks
This should give you all the posts where it is associated with the "Swift" tag.
var books = dbContext.Books.Where(s => s.Tags.Any(f => f.Name == "Swift")).ToList();
If you want to get the result based on the TagId, change the condition in the predicate.
var books = dbContext.Books.Where(s => s.Tags.Any(f => f.Id== 17)).ToList();

Add a column to a many to many relation table code first entity framework

I have 2 classes which have a many to many relation.
public class Document
{
public int Id { get; set; }
public string Name { get; set; }
public bool AvailableOffline { get; set; }
public string URL { get; set; }
public virtual ICollection<Profile> Profiles { get; set; }
}
public class Profile
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual ICollection<Document> Documents { get; set; }
}
On each profile I wish to have a SortOrder field for each document. So I made the joined table explicit in another class
public class ProfileDocuments
{
[Key, Column(Order = 0)]
public int DocumentId { get; set; }
[Key, Column(Order = 1)]
public int ProfileId { get; set; }
public int SortOrder { get; set; }
[ForeignKey("DocumentId")]
public virtual Document Document { get; set; }
[ForeignKey("ProfileId")]
public virtual Profile Profile { get; set; }
}
But when I update the database the table for this last class will not have a column for SortOrder. It only holds the 2 foreign keys. How can I tell EF to generate this table with my column?
When a junction table in a many-to-many association should contain more information than just the two foreign keys, it's no longer possible to map the association as a 'pure' many-to-many (with hidden junction class).
You need an explicit class in the class model to address the extra information (as you already found out), but this also changes the association into 1-n-1:
class Document
{
...
public virtual ICollection<ProfileDocument> ProfileDocuments { get; set; }
}
class Profile
{
...
public virtual ICollection<ProfileDocument> ProfileDocuments { get; set; }
}

Navigation property from dependent to principal

I have two Entities
public class Person
{
public virtual int ID { get; set; }
public virtual string Name { get; set; }
public virtual Employee Employee { get; set; }
}
public class Employee
{
public virtual int ID { get; set; }
public virtual string Code { get; set; }
public virtual int PersonId { get; set; }
[ForeignKey("PersonId")]
public virtual Person Person { get; set; }
}
in my business first we create person then we create an employee by selecting a person, while selecting person for the employee i want to select only the persons who are not associated to employee, i couldn't figure how to configure the Employee property in Person Entity
If you are selecting people that aren't related to a specific employee then you shouldn't have a property for that. You should only have link to related entities. Try doing this in LINQ it should get you all people that don't have a relation to an employee.
var people = context.People.Where(x => x.Employee == null);
public class Person
{
public virtual int ID { get; set; }
public virtual string Name { get; set; }
public virtual Employee Employee { get; set; }
}
public class Employee
{
public virtual int ID { get; set; }
public virtual string Code { get; set; }
public virtual int PersonId { get; set; }
[ForeignKey("PersonId")]
[InverseProperty("Employee")]
public virtual Person Person { get; set; }
}
Think that should do it, inverse property creates the mapping so only needs to be done from one side.
Hope this is what you were looking for.
I figured out an answer, don't know if it's the best!
jobQuery = jobQuery.Where(jb => !Context.Employees.Any(emp => emp.JobId == jb.Id));

Allow NULL Foreign Keys with SQLite-net-extensions

I'd like to know if I can, with a SQLite database and SQLite-Net Exensions, add 2 foreign keys to the same table with, each time, one of the foreign keys empty.
My structure is the following:
[Table("Picture")]
public class Picture
{
[PrimaryKey]
public int Id { get; set; }
public string Name { get; set; }
[ForeignKey(typeof(Contact))] // => Allow Null ?
public string TokenContact { get; set; }
[ForeignKey(typeof(Profile))] // Allow Null ?
public string TokenProfile { get; set; }
}
[Table("Contact")]
public class Contact
{
[PrimaryKey]
public string Token {get;set;}
[OneToMany]
public ObservableCollection<Picture> CollectionPicture {get; set;}
}
[Table("Profile")]
public class Profile:Contact
{
// Some other properties...
}
Thanks for your advices !

Code first one to one foreign key

I have two model class, where I want to make one-to-one relation. When I make migration, I get an error:
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint
"FK_dbo.Uzytkownik_dbo.UserProfile_UserId". The conflict occurred in
database "db_wydarzenia", table "dbo.UserProfile", column 'UserId'.
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
}
[Table("Uzytkownik")]
public class Uzytkownik
{
[Key]
public int UzytkownikID { get; set; }
public int UserId { get; set; }
public string Imie { get; set; }
public string Nazwisko { get; set; }
public string Telefon { get; set; }
public string Email { get; set; }
[ForeignKey("UserId")]
public UserProfile UserProfile { get; set; }
}
EDIT:
Problem solved :)
I remove all data from uzytkownik table and it's go.
If you want one-to-one - you cannot have both the primary-key and the foreign-key specified. One-to-one is modeled via primary-keys (pk == pk), otherwise it becomes 'multiplicity' (and just typical one-to-many).
To get what you want just remove your other PK - and user UserId as both primary and fk...
[Table("Uzytkownik")]
public class Uzytkownik
{
// [Key] public int UzytkownikID { get; set; }
[Key]
public int UserId { get; set; }
[ForeignKey("UserId")]
public UserProfile UserProfile { get; set; }
}

Resources