I dont understand, i have my model.edmx with the two tables:
then i have my 3 tables:
CREATE TABLE [Group].[RecommendedUserGroups]
(
[Groups_GroupId] INT NOT NULL,
[RecommendedUsers_RecommendedUserId] int NOT NULL,
CONSTRAINT [PK_GroupRecommendedUser] PRIMARY KEY CLUSTERED ([Groups_GroupId] ASC, [RecommendedUsers_RecommendedUserId] ASC),
CONSTRAINT [FK_RecommendedUsers_RecommendedUserGroups] FOREIGN KEY ([RecommendedUsers_RecommendedUserId]) REFERENCES [Zinc].[RecommendedUsers] ([RecommendedUserId]),
CONSTRAINT [FK_Groups_RecommendedUserGroups] FOREIGN KEY ([Groups_GroupId]) REFERENCES [Group].[Groups] ([GroupId])
)
CREATE TABLE [Group].[Groups]
(
[GroupId] INT NOT NULL IDENTITY(1, 1),
[Customers_CustomerId] INT NOT NULL,
[Name] NVARCHAR(128) NOT NULL,
[IsArchived] BIT NOT NULL,
[SmallImageUrl] NVARCHAR (256) NULL,
[MediumImageUrl] NVARCHAR (256) NULL,
[LargeImageUrl] NVARCHAR (256) NULL,
[AllowFiltering] BIT NOT NULL DEFAULT 0,
[IsSegment] BIT NOT NULL CONSTRAINT DF_Groups_IsSegment DEFAULT 0,
CONSTRAINT [PK_Groups] PRIMARY KEY CLUSTERED ([GroupId] ASC),
CONSTRAINT [FK_Groups_Customers] FOREIGN KEY ([Customers_CustomerId]) REFERENCES [Zinc].[Customers] ([CustomerId]),
)
CREATE TABLE [Zinc].[RecommendedUsers]
(
[RecommendedUserId] INT IDENTITY(1,1) NOT NULL,
[Firstname] NVARCHAR (50) NOT NULL,
[Surname] NVARCHAR (50) NOT NULL,
[Email] NVARCHAR (256) NOT NULL,
[Department] NVARCHAR (256) NULL,
[JobTitle] NVARCHAR (256) NULL,
[DateAndTimeProcessed] DATETIME NULL,
[Users_UserId] INT NOT NULL,
[DateAndTimeRecommended] DATETIME NOT NULL,
[AssignedUserId] INT NULL,
CONSTRAINT [PK_RecommendedUsers] PRIMARY KEY CLUSTERED ([RecommendedUserId] ASC),
)
then my entities:
namespace Zinc.Entities
{
public class RecommendedUser
{
#region Properties
public virtual int RecommendedUserId { get; set; }
public virtual string Firstname { get; set; }
public virtual string Surname { get; set; }
public virtual string Email { get; set; }
public virtual string Department { get; set; }
public virtual string JobTitle { get; set; }
public virtual DateTime? DateAndTimeProcessed { get; set; }
public virtual int Users_UserId { get; set; }
public virtual DateTime? DateAndTimeRecommended { get; set; }
public virtual int AssignedUserId { get; set; }
public virtual ICollection<Group.Group> Groups { get; set; }
#endregion
}
}
namespace Zinc.Entities.Group
{
public class Group
{
#region Properties
public virtual int GroupId { get; set; }
public virtual string Name { get; set; }
public virtual bool IsArchived { get; set; }
public virtual bool IsSegment { get; set; }
public virtual bool AllowFiltering { get; set; }
public virtual string SmallImageUrl { get; set; }
public virtual string MediumImageUrl { get; set; }
public virtual string LargeImageUrl { get; set; }
public virtual Entities.Customer Customer { get; set; }
#endregion
#region ICollections
//i am only concerned with recommended user so will just put this collection here
private ICollection<RecommendedUser> _groupRecommendedUsers;
public virtual ICollection<RecommendedUser> RecommendedUsers
{
get
{
if (_groupRecommendedUsers == null)
_groupRecommendedUsers = new List<RecommendedUser>();
return _groupRecommendedUsers;
}
set
{
_groupRecommendedUsers = value;
}
}
so when i save the groups with the recommende user details, it writes to my recommendeuser table but does not update my RecommendedUserGroups table??
can some one help please? i use mvc3
The primary key of your RecommendedUserGroups table, should be both fields in the table.
The way that the table is defined each group can only have one member.
Related
I am creating a SQLITE table in my Xamarin application like this:
public class ClickHistory
{
[PrimaryKey, NotNull]
public string Yymmdd { get; set; }
public int DayOfYear { get; set; }
public int Year { get; set; }
public int Month { get; set; }
public int Day { get; set; }
public int BtnACount { get; set; }
public int BtnBCount { get; set; }
public int BtnCCount { get; set; }
public int BtnDCount { get; set; }
}
db2.CreateTable<ClickHistory>();
Can someone help me by telling me how I can set default values for the BtnACount, BtnBCount, BtnCCount, BtnDCount columns to a value of 0. Right now when I do an insert but don't specify those columns it defaults to null.
Please note the suggested solution for this in another question that a person marked as a duplicate for me:
[NotNull, Default(value: true)]
Does not work in the version of SQLITE with Xamarin
If Default is supported by your SQLite, then use Default attribute
[Table("blabla")]
public class Blabla {
[PrimaryKey, AutoIncrement, NotNull]
public int id { get; set; }
[NotNull,Default(value:1)]
public int bleh { get; set; }
}
If Default is not supported by your SQLite,you can simply assign default value like this:
[Table("blabla")]
public class Blabla {
[PrimaryKey, AutoIncrement, NotNull]
public int id { get; set; }
[NotNull]
public int bleh { get; set; } = 1;
}
I prefer second way.
I have a table which has the Id as primary key, I want to have a composite unique key on Code and Value column. I'm trying in this way.
[Table("Test")]
public class Test: FullAuditedEntity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public virtual int Code { get; set; }
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public virtual int Value { get; set; }
But it's making the composite primary key not unique key.
Try this:
public class SomeClass : Entity<int>
{
[Column("Code")]
public override int Id {get; set;}
public virtual string Name { get; set; }
}
[DatabaseGenerated(DatabaseGeneratedOption.None)] will make the Database to NOT create the Code column. What you need in reality is to override the Id and rename it to Code.
And to have a composite key, simply add
[Key]
public virtual int Value { get; set; }
field.
Adding solution for others.
Don't modify anything just add the below line
modelBuilder.Entity<Test>(b =>
{
b.HasIndex(e => new { e.Code, e.Value}).IsUnique();
});
I have two classes
public class Project
{
[Key]
public int ID { get; set; }
public string Name { get; set; }
public int ManagerID { get; set; }
public int CoordID { get; set; }
[ForeignKey("ManagerID")]
public virtual Employee Manager { get; set; }
[ForeignKey("CoordID")]
public virtual Employee Coord { get; set; }
}
public class Employee
{
[Key]
public int EmpID { get; set; }
public string Name { get; set; }
[InverseProperty("ManagerID")]
public virtual ICollection<Project> ManagerProjects { get; set; }
[InverseProperty("CoordID")]
public virtual ICollection<Project> CoordProjects { get; set; }
}
The ManagerID and CoordID map to the EmpID column of the Employee table.
I keep getting an error for Invalid Columns becauce EF is not able to map correctly. I think it is looking for wrong column.
I think InverseProperty is used to refer to the related navigation property, not the foreign key, e.g.
public class Employee
{
[Key]
public int EmpID { get; set; }
public int Name { get; set; }
[InverseProperty("Manager")]
public virtual ICollection<Project> ManagerProjects { get; set; }
[InverseProperty("Coord")]
public virtual ICollection<Project> CoordProjects { get; set; }
}
Also, is there a reason why your names are ints and not strings?
Best guess would be to use fluent API in your context via OnModelCreating. By renaming the column, EF can't figure out the original object to map so it's confused. However, Fluent API allows you to manually specify the map using something like the following:
public class MyContext : DbContext
{
public DbSet<Employee> Employees { get; set; }
public DbSet<Project> Projects { get; set; }
protected override OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Project>()
.HasRequired(x => x.Manager)
.WithMany(x => x.ManagerProjects)
.HasForeignKey(x => x.ManagerID);
modelBuilder.Entity<Project>()
.HasRequired(x => x.Coord)
.WithMany(x => x.CoordProjects)
.HasForeignKey(x => x.CoordID);
}
}
I need to configure a relation with following classes:
User have or not a profile. Structure:
User: UserID, Username, Password
Profile: UserID, FullName, Address, Phone
public class User
{
#region Feilds
public int UserID { get; set; }
public string Email { get; set; }
public string Password { get; set; }
#endregion
public virtual Profile Profile { get; set; }
}
public class Profile
{
#region Fields
public string FirstName { get; set; }
public string LastName { get; set; }
public string Phone { get; set; }
public string Address { get; set; }
#endregion
public virtual User User { get; set; }
}
Configuration:
public class UserConfiguration : EntityTypeConfiguration<User>
{
public UserConfiguration()
: base()
{
// Primary Key
this.HasKey(p => p.UserID);
//Foreign Key
this.HasOptional(p => p.Profile).
WithMany().
HasForeignKey(p => p.UserID);
}
}
Error:
System.Data.Edm.EdmEntityType: : EntityType 'Profile' has no key defined. Define the key for this EntityType.
System.Data.Edm.EdmEntitySet: EntityType: EntitySet �Profiles� is based on type �Profile� that has no keys defined.
Please help.
Thanks.
Each entity in Entity framework must have primary key defined. Your profile entity should look like to get out of your current error:
public class Profile
{
#region Fields
public int Id {get;set;}
public string FirstName { get; set; }
public string LastName { get; set; }
public string Phone { get; set; }
public string Address { get; set; }
#endregion
public virtual User User { get; set; }
}
Ok - first off apologies - I'm a front end developer (HTML, CSS and JS) trying to do stuff with data - never pretty!
I have a 'Page', that can can have one or many 'Series'. These 'Series' can hold one or many 'Collections' and these 'Collections' can be related to more than one 'Series'. The 'Collection's can hold one or more 'Titles'. This is how I've structured my db:
CREATE TABLE [dbo].[Pages] (
PageId INT NOT NULL PRIMARY KEY,
[Title] NCHAR(50) NOT NULL
)
CREATE TABLE [dbo].[Series] (
[SeriesId] INT NOT NULL,
[Title] NCHAR (50) NOT NULL,
[PageId] INT NOT NULL,
PRIMARY KEY CLUSTERED ([SeriesId] ASC),
CONSTRAINT [FK_Series_Pages] FOREIGN KEY ([PageId]) REFERENCES [Pages]([PageId])
);
CREATE TABLE [dbo].[Collections] (
[CollectionId] INT NOT NULL,
[Title] NCHAR (50) NOT NULL,
PRIMARY KEY CLUSTERED ([CollectionId] ASC)
);
CREATE TABLE [dbo].[SeriesCollections] (
[SeriesCollectionId] INT NOT NULL,
[SeriesId] INT NOT NULL,
[CollectionId] INT NOT NULL,
PRIMARY KEY CLUSTERED ([SeriesCollectionId] ASC),
CONSTRAINT [FK_SeriesCollections_Series] FOREIGN KEY ([SeriesId]) REFERENCES [Series]([SeriesId]),
CONSTRAINT [FK_SeriesCollections_Collections] FOREIGN KEY ([CollectionId]) REFERENCES [Collections]([CollectionId])
);
CREATE TABLE [dbo].[Titles] (
[TitleId] INT NOT NULL,
[Title] NCHAR (100) NOT NULL,
[SeriesCollectionId] INT NOT NULL,
PRIMARY KEY CLUSTERED ([TitleId] ASC),
CONSTRAINT [FK_Titles_SeriesCollections] FOREIGN KEY ([SeriesCollectionId]) REFERENCES [SeriesCollections]([SeriesCollectionId])
Using Entity Framework I have the following:
public DbSet<Page> Pages { get; set; }
public DbSet<Series> Series { get; set; }
public DbSet<Collection> Collections { get; set; }
public DbSet<SeriesCollection> SeriesCollections { get; set; }
public DbSet<Title> Titles { get; set; }
In the view I want to get the following.
For a given 'Page' (id), I want all the 'Series' and within each of those 'Series', be able to list each of the 'Titles' and its associated 'Collection'.
First off - is my db set up correctly? Secondly, I'm struggling with the db call and viewmodels that would return this.
If anyone can help that'd be great
Thanks in advance
The 'Collection's can hold one or more 'Titles'.
Because of this I would modify your DB table schema:
In table Titles replace [SeriesCollectionId] by [CollectionId], directly refering to the Collections table.
In table SeriesCollections remove your PK [SeriesCollectionId] and make instead the remaining two fields [SeriesId] and [CollectionId] to a composite primary key.
Now, you can model a many-to-many relationship between Series and Collections with EF. Then the join table SeriesCollections isn't part of your model anymore. It's just a hidden table in the DB which is managed by EF. Therefore you can remove public DbSet<SeriesCollection> SeriesCollections { get; set; }.
The model classes could then look like this:
public class Page
{
public int PageId { get; set; }
[Required]
[MaxLength(50)]
pubic string Title { get; set; }
public ICollection<Series> Series { get; set; }
}
public class Series
{
public int SeriesId { get; set; }
[Required]
[MaxLength(50)]
pubic string Title { get; set; }
public int SeriesId { get; set; }
public int PageId { get; set; } // FK property, helpful but not required
public Page Page { get; set; }
public ICollection<Collection> Collections { get; set; }
}
public class Collection
{
public int CollectionId { get; set; }
[Required]
[MaxLength(50)]
pubic string Title { get; set; }
public ICollection<Series> Series { get; set; }
public ICollection<Title> Titles { get; set; }
}
public class Title
{
public int TitleId { get; set; }
[Required]
[MaxLength(100)]
pubic string TTitle { get; set; } // must be other name then class
public int CollectionId { get; set; } // FK property
public Collection Collection { get; set; }
}
For many-to-many mapping you need Fluent API:
public class MyContext : DbContext
{
public DbSet<Page> Pages { get; set; }
public DbSet<Series> Series { get; set; }
public DbSet<Collection> Collections { get; set; }
public DbSet<Title> Titles { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Series>()
.HasMany(s => s.Collections)
.WithMany(c => c.Series)
.Map(a =>
{
a.MapLeftKey("SeriesId");
a.MapRightKey("CollectionId");
a.ToTable("SeriesCollections");
});
}
}
EF will figure out all other relationships by convention, I believe.
For a given 'Page' (id), I want all the 'Series' and within each of
those 'Series', be able to list each of the 'Titles' and its
associated 'Collection'.
With the model above you could then try:
var page = context.Pages.Where(p => p.PageId == id)
.Include(p => p.Series.Select(s => s.Collections.Select(c => c.Titles)))
.SingleOrDefault();
It would select the page which contains a list of series with a list of collections with a list of titles.
Not sure if this is exactly what you want, just an untested starting point.
(BTW: You can write your classes first (Code-First) and let EF create your database tables. It's easier during design phase when you want to try some mappings, imo.)
Edit
One thing I forgot: If you really want non-variable fixed length string fields (NCHAR(50)) you must define this explicitely in Fluent API. By default EF would assume NVARCHAR(50) fields with the mapping above. Setting to fixed length columns would look like this:
modelBuilder.Entity<Page>().Property(p => p.Title).IsFixedLength();