Composite-primary key issue in entity framework code first - entity-framework

I have an issue in entity framework code first, three table in database as follows:
CREATE TABLE [Food](
PK [FoodId] [int] NOT NULL,
[FoodName] [varchar](50) NULL)
CREATE TABLE [Fruit](
PK [FruitId] [int] NOT NULL,
[FruitName] [varchar](50) NULL)
CREATE TABLE [FoodFruit](
PK, FK [FoodId] [int] NOT NULL,
PK, FK [FruitId] [int] NOT NULL)
The Model will only generate Food, Fruit entities.
But if I add a new column [Notes] to FoodFruit table, such as Notes:
CREATE TABLE [FoodFruit](
PK, FK [FoodId] [int] NOT NULL,
PK, FK [FruitId] [int] NOT NULL,
[Notes] [varchar](50) NULL)
The Model will generate Food, Fruit and FoodFruit entities.
So, I'm confused it, why the first one doesn't generate the FoodFruit entity.

That is correct behavior. In the first case your FoodFruit table is just database helper to model many-to-many relationship. EF doesn't need such helper in conceptual model so it hides this table behind directly modeled many-to-many relation. In the second case the table has additional data - it becomes full entity, not just junction table for relationship. EF detects it and map it as a new class.

Related

Entity Framework Many TO Many Relationship with Primary Key

I have the following Schema:
User Table: (Primary Key)
UserId
CustomerId
Role Table: (Primary Key)
UserId
CustomerId
UserRole Table:
UserRoleId (UNIQUEIDENTIFIER (newsequentialid)) Primary Key
UserId
Customerid
RoleId
Those tables participate in many to many relationship (UserRole). I am using Entity Framework code first with mapping classes to define the database tables. So, In my mapping class for User Table, I have the following:
this.HasMany(u => u.Roles)
.WithMany()
.Map(m =>
{
m.MapLeftKey(new string[] { "CustomerID", "UserID" });
m.MapRightKey(new string[] {"CustomerID", "RoleID"});
m.ToTable("UserRoles");
}
);
Entity framework is failing with this message:
"One or more validation errors were detected during model generation:
CustomerID: Name: Each property name in a type must be unique. Property name 'CustomerID' is already defined.
UserRole: EntityType: EntitySet 'UserRole' is based on type 'UserRole' that has no keys defined.
is it possible to tell Code First that the Primary Key for my "UserRole" is UserRoleId?
The issue is when Entity Framework tries to create the UserRole Table, it would use all columns of MapLeftKey and MapRightKey to Create UserRole with PrimaryKey that has all those columns.
Any suggestions?
You need to model your classes similar to your DB, why don't you simply add the association tables? I mocked up your DB and there is no problem as long as you model all the tables.
Test it for yourself, create an EF project .edmx using code first from existing DB, I think the answer will be obvious.

EntityFramework - many-to-many reference in the DB without a backreference in the model

In my application users can define Parameters, and then create SlideSets based on a grouping of parameters.
I am using code-first Entity Framework 5.0 and I have the following model:
class SlideSet {
public ICollection<Parameter> Parameter
}
class Parameter {}
A parameter might be used by many slidesets or none at all. However, in my domain a parameter has no need to reference a SlideSet, they are in separate bounded contexts (both SlideSet and Parameter are Aggregate Roots). As such, I don't want to put a reference from Parameter to SlideSet.
The table model (I don't care about table/column names) that I want is
Table SlideSet
Table Param
Table SlideSetParam
FK_SlideSet
FK_Param
I know I could model this by introducing a ParameterGroup entity or a Param.SlideSets collection, but it would exist solely for ORM mapping purposes (and cause serialization issues). Is there any other way to tell EF to generate this table model from my entities?
This should make you a Parameter w/o a navigation property:
modelBuilder.Entity<SlideSet>()
.HasMany(x => x.Parameters)
.WithRequired();
EDIT:
Based on the comment - that should be all together similar. This seems to work nicely what you're trying to do....
modelBuilder.Entity<SlideSet>()
.HasMany(x => x.Parameters)
.WithMany();
...and you can use it either way:
var slideset = new SlideSet { Parameters = new []
{
new Parameter{},
new Parameter{},
new Parameter{},
new Parameter{},
}
};
var slideset2 = new SlideSet { };
db.SlideSets.Add(slideset);
db.SaveChanges();
var slidesets = db.SlideSets.ToList();
var parameters = db.Parameters.ToList();
Console.WriteLine("");
db.SlideSets.Add(slideset2);
db.SaveChanges();
slidesets = db.SlideSets.ToList();
parameters = db.Parameters.ToList();
Console.WriteLine("");
...and the SQL:
CREATE TABLE [dbo].[Parameters] (
[ParameterID] [int] NOT NULL IDENTITY,
CONSTRAINT [PK_dbo.Parameters] PRIMARY KEY ([ParameterID])
)
CREATE TABLE [dbo].[SlideSets] (
[SlideSetID] [int] NOT NULL IDENTITY,
CONSTRAINT [PK_dbo.SlideSets] PRIMARY KEY ([SlideSetID])
)
CREATE TABLE [dbo].[SlideSetParameters] (
[SlideSet_SlideSetID] [int] NOT NULL,
[Parameter_ParameterID] [int] NOT NULL,
CONSTRAINT [PK_dbo.SlideSetParameters] PRIMARY KEY ([SlideSet_SlideSetID], [Parameter_ParameterID])
)
CREATE INDEX [IX_SlideSet_SlideSetID] ON [dbo].[SlideSetParameters]([SlideSet_SlideSetID])
CREATE INDEX [IX_Parameter_ParameterID] ON [dbo].[SlideSetParameters]([Parameter_ParameterID])
ALTER TABLE [dbo].[SlideSetParameters] ADD CONSTRAINT [FK_dbo.SlideSetParameters_dbo.SlideSets_SlideSet_SlideSetID] FOREIGN KEY ([SlideSet_SlideSetID]) REFERENCES [dbo].[SlideSets] ([SlideSetID]) ON DELETE CASCADE
ALTER TABLE [dbo].[SlideSetParameters] ADD CONSTRAINT [FK_dbo.SlideSetParameters_dbo.Parameters_Parameter_ParameterID] FOREIGN KEY ([Parameter_ParameterID]) REFERENCES [dbo].[Parameters] ([ParameterID]) ON DELETE CASCADE
...this makes the original tables practically 'agnostic' of the relationships (many-to-many) - while index table is automatically generated in the background.
You can also further customize that and make your own SlideSetParam (e.g. if you'd want to add additional fields there) with pretty much the same layout - just Parameters would have to point to that instead.

Accessing table with only foreign Keys in Entity Data Framework

i am new to Entity Data framework
i have tables
Actions ( Actionid (pk) ,Actionname , ... )
Roles ( Roleid(pk) , Rolename , .... )
ActionRoles( Actionid(pk,fk) , Roleid(fk) ) [Mapping Table]
Please Suggest me the LINQ to get the RoleNames for Perticular ActionID
(Note : there is No class created with Name ActionRoles in entitydesigner.cs as because it doesn't have any other column name then ActionId and RoleID )
Thank you in Advance
When you have a link table like this, adding all tables to the Entity Model should create 2 way relationship Properties between the 2 end tables, hiding the link table completely allowing you to access via something like:
IEnumerable<string> roleNames = Entities.Actions
.First(a => a.Actionid == actionid)
.Roles
.Select(r => r.Rolename);
where actionid is an int variable containing the actionid you're interested in.
For a discussion of how to handle many-to-many relationships such as this (both foreign keys must be in the ActionRoles primary key as indicated in the comment to your question), see these tutorials:
For EF 4.0: http://www.asp.net/entity-framework/tutorials/the-entity-framework-and-aspnet-–-getting-started-part-5
For Ef 4.1: http://www.asp.net/entity-framework/tutorials/updating-related-data-with-the-entity-framework-in-an-asp-net-mvc-application

Entity Framework This property descriptor does not support the SetValue

below are my entities which i have created using entity frame work.
retailer
id
name
childs(navigation)
generated database schema
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] nvarchar NOT NULL
childern
id
name
RETAILER(navigation)
generated database schema
[Id] [int] IDENTITY(1,1) NOT NULL,
[name] nvarchar NOT NULL
[Retailer_Id] [int] NOT NULL,
As you can see in the above model the relationship is 1 retailer can have 0 or 1 child. my problem is when i create a new child and set the retailer navigation property of it to a retailer entity it throws the following exception.how do i solve it
Error while setting property
'retailer': 'This property descriptor
does not support the SetValue
method.'.
Does the Retailer navigation property have its Setter property set to Public?

Entity Framework with POCO Template and FKs in Model - Null Ref Exception

I'm using Entity Framework 4 with the POCO code generation template from Microsoft downloaded from the Visual Studio gallery. I am also leaving the default option to "Include foreign keys in model" selected when generating the EF model from the database.
I've been able to reproduce this problem with a very simple model, only two tables/classes in an optional one-to-many relationship. In this case, I'm using an Address and a Person. A Person can have one or zero addresses, and an Address can have zero to many People.
The tables look like this:
CREATE TABLE [dbo].[Person](
[PersonID] [uniqueidentifier] NOT NULL,
[FirstName] [nvarchar](50) NULL,
[LastName] [nvarchar](50) NULL,
[AddressID] [uniqueidentifier] NULL,
CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED ([PersonID] ASC )
CREATE TABLE [dbo].[Address](
[AddressID] [uniqueidentifier] NOT NULL,
[Street1] [nvarchar](50) NOT NULL,
[Street2] [nvarchar](50) NULL,
[City] [nvarchar](50) NOT NULL,
[State] [char](2) NOT NULL,
[Country] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Address] PRIMARY KEY CLUSTERED ([AddressID] ASC)
ALTER TABLE [dbo].[Person] WITH CHECK ADD CONSTRAINT [FK_Person_Address]
FOREIGN KEY([AddressID])
REFERENCES [dbo].[Address] ([AddressID])
When I try to create an Address object and add it to an existing Person object pulled from the database, I get a null reference exception:
TestPOCOEntities ctx = new TestPOCOEntities();
var person = ctx.People.FirstOrDefault(p => p.PersonID == new Guid("58AD37B4-1EBE-4649-940C-A141732C9901"));
var addr = new Address {AddressID = Guid.NewGuid(), Street1 = "123 Main St"};
person.Address = addr; // This line throws the exception
ctx.SaveChanges();
Digging into the call stack, the exception isn't being thrown from my code, or even the template-generated code, but inside the runtime dynamic proxy for the Person class in the AddressID setter. (Specifically, the System.Data.Objects.EntityEntry.FixupEntityReferenceByForeignKey(EntityReference reference) method.)
This exception does not occur if I use the default EF code generation instead of the POCO template. It also does not occur if I use the POCO template but uncheck the "Include foreign keys in model" checkbox when generating the model from the database.
I can get the error to go away if I add the following:
var addr = new Address {AddressID = Guid.NewGuid(), Street1 = "123 Main St"};
ctx.Addresses.AddObject(addr); // Adding this line...
person.Address = addr; // Means no more exception here!
I don't see why the combination of using the POCO template and including foreign keys in the model should require this kind of code change when interacting with my persistent objects. Is this a known bug? Am I missing something? Is this by design for some reason?
this is a potential bug of EF, usually then refresh a created entity (resave changes with new data) solution:
http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/832af255-d1c2-41d5-9e95-9cdf3b15bb57
the cheat is add the entity to the collection context first
second assign to the father entity
third, savechanges normally!
enjoy