Invalid column name in EF - entity-framework

I have a situation where EF is trying to get a field value from the table "VideoClip" that I didn't ask it to get.
The complete generated query looks like this:
SELECT
[Project1].[Id] AS [Id],
[Project1].[NewsItemId] AS [NewsItemId],
[Project1].[VideoClipId] AS [VideoClipId],
[Project1].[DisplayOrder] AS [DisplayOrder],
[Project1].[Video_Id] AS [Video_Id]
FROM ( SELECT
[Extent1].[Id] AS [Id],
[Extent1].[NewsItemId] AS [NewsItemId],
[Extent1].[VideoClipId] AS [VideoClipId],
[Extent1].[DisplayOrder] AS [DisplayOrder],
[Extent1].[Video_Id] AS [Video_Id]
FROM [dbo].[NewsItemVideoClip] AS [Extent1]
WHERE [Extent1].[NewsItemId] = #p__linq__0
) AS [Project1]
ORDER BY [Project1].[DisplayOrder] DESC
However, my NewsItemVideoClip entity class looks like this:
public class NewsItemVideoClip : Entity
{
public virtual int NewsItemId { get; set; }
public virtual int VideoClipId { get; set; }
public virtual int DisplayOrder { get; set; }
public virtual NewsItem NewsItem { get; set; }
public virtual VideoClip VideoClip { get; set; }
}
The mapping:
public class NewsItemVideoClipEntityMapping
: EntityTypeConfiguration<NewsItemVideoClip>
{
public NewsItemVideoClipEntityMapping()
{
//configure key and properties
HasKey(c => c.Id);
this.HasRequired(x => x.NewsItem)
.WithMany(x => x.NewsItemVideoClips)
.HasForeignKey(x => x.NewsItemId);
this.HasRequired(x => x.VideoClip)
.WithMany(x => x.NewsItemVideos)
.HasForeignKey(x => x.VideoClipId);
//configure table map
ToTable("NewsItemVideoClip");
}
}
The LINQ query:
public IList<NewsItemVideoClip> GetVideoClips(int newsItemId)
{
var query = from nvc in _newsItemVideoClipRepository.GetAll()
where nvc.NewsItemId == newsItemId
orderby nvc.DisplayOrder descending
select nvc;
var newsItemVideoClips = query.ToList();
return newsItemVideoClips;
}
Howcome EF gives me: Invalid column name 'Video_Id'?

Based on your diagram, VideoClip has a VideoId which I guess is your intended foreign key to Video. Video_Id would be the default foreignkey name for the foreign key in the abscence of mapping that would name it otherwise. So probably need a .HasForeignKey(x => x.VideoId); to your VideoClip mapping.

Related

EF code first from database 0..1 to many relationship

I am trying to generated an entity framework code first model from an existing database (without changing the database schema). This database has been used in the past to generate edmx models and I am trying to achieve the equivalent model using Fluent Api or data annotations.
The relationship I have been unable to reproduce is 0..1 to many using a join table (not a nullable foreign key).
So it would look something like this:
TableA
{
ID (PrimaryKey)
TableB (0 or 1)
}
JoinTable
{
TableA_FK (PrimaryKey, ForeignKey),
TableB_FK (ForeignKey)
}
TableB
{
ID (PrimaryKey)
TableAs (Many)
}
Is this achievable in the code first style or will I have to generate an edmx model in order to use this database in EF without changing its schema?
Many thanks,
Phil
Here is an example without using a JoinTable class. The join table is configured through the fluent api.
class DataContext : DbContext
{
public DataContext(string connectionString)
: base(connectionString)
{ }
public DbSet<TableA> TableA { get; set; }
public DbSet<TableB> TableB { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<TableA>().ToTable("TableA");
modelBuilder.Entity<TableB>().ToTable("TableB");
modelBuilder.Entity<TableB>()
.HasMany(x => x.TableAs)
.WithMany()
.Map(m =>
{
m.ToTable("JoinTable");
m.MapLeftKey("TableA_FK");
m.MapRightKey("TableB_FK");
});
}
}
class TableA
{
public int ID { get; set; }
public TableB TableB { get; set; }
}
class TableB
{
public int ID { get; set; }
public ICollection<TableA> TableAs { get; set; }
}
This will generate the following migration script, which looks like the schema you have.
public override void Up()
{
CreateTable(
"dbo.TableA",
c => new
{
ID = c.Int(nullable: false, identity: true),
TableB_ID = c.Int(),
})
.PrimaryKey(t => t.ID)
.ForeignKey("dbo.TableB", t => t.TableB_ID)
.Index(t => t.TableB_ID);
CreateTable(
"dbo.TableB",
c => new
{
ID = c.Int(nullable: false, identity: true),
})
.PrimaryKey(t => t.ID);
CreateTable(
"dbo.JoinTable",
c => new
{
TableA_FK = c.Int(nullable: false),
TableB_FK = c.Int(nullable: false),
})
.PrimaryKey(t => new { t.TableA_FK, t.TableB_FK })
.ForeignKey("dbo.TableB", t => t.TableA_FK, cascadeDelete: true)
.ForeignKey("dbo.TableA", t => t.TableB_FK, cascadeDelete: true)
.Index(t => t.TableA_FK)
.Index(t => t.TableB_FK);
}
If I've understood correctly, the following code using only data annotations should create your model.
public class TableA
{
public int ID { get; set; }
public JoinTable JoinTable { get; set; }
}
public class TableB
{
public int ID { get; set; }
public List<JoinTable> JoinTables{ get; set; }
}
public class JoinTable
{
[Key, ForeignKey("TableA")]
public int TableA_FK { get; set; }
[ForeignKey("TableB")]
public int TableB_FK { get; set; }
public TableA TableA { get; set; }
public TableB TableB { get; set; }
}
Interestingly, EF does not perform a round trip back to the original, if you generate the code-first models from the database model that this code creates then EF simplifies the model and removes the join table and creates a nullable foreign key.
Let me know if this works.
I may be wrong, but I believe you're missing some concepts here...
Why you have a JoinTable if it's doesn't have any column besides its foreign keys? It doesn't make sense... IHMO a nullable foreign key in TableA would be correct way.
When you work with Code-First it means that everything in your database will be represented by CODE. There's no reason to have a table in your database but not in your code...
EDMX handles that relationship because it uses "Associations" https://msdn.microsoft.com/en-us/data/jj713299#Overview
...backing to the code-first, you can represent your database like this:
public class JoinTable
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int TableA_FK { get; set; }
public int TableB_FK { get; set; }
//a future property here
public virtual TableA TableA { get; set; }
public virtual TableB TableB { get; set; }
}
public partial class TableA
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int TableAId { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
public virtual JoinTable JoinTable { get; set; }
}
public partial class TableB
{
public TableB()
{
JoinTable = new HashSet<JoinTable>();
}
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int TableBId { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
public virtual ICollection<JoinTable> JoinTable { get; set; }
}
}
public partial class Model1 : DbContext
{
public Model1()
: base("name=Model1")
{
}
public virtual DbSet<JoinTable> JoinTable { get; set; }
public virtual DbSet<TableA> TableA { get; set; }
public virtual DbSet<TableB> TableB { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<TableA>()
.HasOptional(e => e.JoinTable)
.WithRequired(e => e.TableA);
modelBuilder.Entity<TableB>()
.HasMany(e => e.JoinTable)
.WithRequired(e => e.TableB)
.HasForeignKey(e => e.TableB_FK)
.WillCascadeOnDelete(false);
}
}

Defining relationships with existing database in code first

I have an existing database with two tables: MemData and MemPhone.
MemData has the following structure
uidMemberId (PK, uniqueidentifier not null)
strFirstName (varchar(50), null)
strLastName (varchar(50), null)
MemPhone has the following structure
uidMemberId (uniqueidentifier not null)
strPhoneNumber (varchar(50), null)
There's no PK on the MemberPhoneNumber table. The two tables are joined by uidMemberId but no foreign keys have been set up in the database.
My MemData Model looks like this:
[Table("MemData")]
public class Member
{
[Key]
public Guid MemberId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual IList<MemberPhoneNumber> MemberPhoneNumbers { get; set; }
}
With the configuration map looking like this:
public MemberMap()
{
Property(t => t.MemberId).HasColumnName("uidMemberID");
Property(t => t.FirstName).HasColumnName("strFirstName");
Property(t => t.LastName).HasColumnName("strLastName");
HasMany(x => x.MemberPhoneNumbers);
}
My MemPhone Model looks like this:
[Table("MemPhone")]
public class MemberPhoneNumber
{
[Key]
public Guid MemberId { get; set; }
public string PhoneNumber { get; set; }
public virtual Member Member { get; set; }
}
With the configuration map looking like this:
public MemberPhoneNumberMap()
{
Property(t => t.MemberId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
Property(t => t.MemberId).HasColumnName("uidMemberID");
Property(t => t.PhoneNumber).HasColumnName("strPhone");
}
In my MVC app, when I call
Uow.Members.GetAll().Include(p => p.MemberPhoneNumbers).ToList()
I get the following error
Invalid column name 'Member_MemberId'.
It should be looking for MemData_uidMemberId instead but I can't figure out what I've missed in the configuration.
Thanks
By default foreign key name will be propertyName _ entityId. That's why EF tries to map to Member_MemberId column. Provide foreign key configuration for one-to-many relationship
public class MemberMap : EntityTypeConfiguration<Member>
{
public MemberMap()
{
ToTable("MemData");
HasKey(m => m.MemberId);
Property(m => m.MemberId).HasColumnName("uidMemberID");
Property(m => m.FirstName).HasColumnName("strFirstName");
Property(m => m.LastName).HasColumnName("strLastName");
HasMany(x => x.MemberPhoneNumbers)
.WithRequired(p => p.Member)
.HasForeignKey(p => p.MemberId);
}
}
Also keep in mind, that you can configure key and table with fluent configuration, you don't need to pollute your entity with data annotations attributes.

How to set default values for foreign keys in Entity Framework code-first models

I'm using Entity Framework 5, code-first.
I have a POCO that looks like this:
public class Order
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Status Status { get; set; }
public Order()
{
this.Status = new Status() { Id = 1 }
}
}
This is mapped fluently like:
public class OrderMap : EntityTypeConfiguration<Order>
{
public OrderMap()
{
ToTable("Order");
HasKey(x => x.Id);
Property(x => x.Id);
Property(x => x.Name).IsRequired();
HasRequired(x => x.Status)
.WithMany(x => x.Orders)
.Map(x => x.MapKey("StatusId"));
}
}
In the database, the Order table has the default value of StatusId set to 1.
However, when adding a new Order, I get this error:
Violation of PRIMARY KEY constraint 'Status_PK'. Cannot insert
duplicate key in object 'dbo.Status'. The duplicate key value is (1)
If I remove the assignment to Status in the Order ctor, then I get this instead:
Cannot insert the value NULL into column 'StatusId', table
'MyDatabase.dbo.Order'; column does not allow nulls. INSERT fails
How can I set default values for foreign key properties?
Provide default status to order via constructor (otherwise new status will be inserted, because whole graph will be in Added state):
public class Order
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Status Status { get; set; }
public Order(Status initialtStatus)
{
Status = initialtStatus;
}
}
And use it like this:
var status = db.Statuses.Find(1);
var order = new Order (status) { Name = "Lazy" };
db.Orders.Add(order);
db.SaveChanges();
UPDATE: Another option is attaching default status entity to context or setting it's state manually:
var order = new Order { Name = "Lazy" };
db.Entry(order.Status).State = EntityState.Unchanged; // avoid inserting
db.Orders.Add(order);
db.SaveChanges();

Many to many relation with the same table with EF4.3 Code First

How to make a configuration with this schema?
CREATE TABLE Entity
(
Id int identity primary key,
Name nvarchar(30)
)
CREATE TABLE Member
(
ParentEntityId references Entity(Id),
ChildEntityId references Entity(Id)
)
Like so:
Model class:
public class Entity
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Entity> Parents { get; set; }
public ICollection<Entity> Children { get; set; }
}
Mapping:
modelBuilder.Entity<Entity>()
.HasMany(e => e.Parents)
.WithMany(e => e.Children)
.Map(m =>
{
m.ToTable("Member");
m.MapLeftKey("ParentEntityId");
m.MapRightKey("ChildEntityId");
});

Setting up code first associations in entity frame 4.1 with multiple tables

Sorry if this is a simple thing, but I'm just learn EF and can't seem to find my answer (or maybe it's just understand what I'm finding).
I have three existing database tables as follows:
Order:
int OrderNo (Primary Key generated by program)
...
OrderDetails:
int OrderNo (Foreign key from Order=>OrderNo; but part of primary key for OrderDetails)
int DetailNo (Part of primary key; generated by program)
...
OrderResults:
int OrderNo (Key from Detail=>OrderNo; but part of primary key for OrderResults)
int DetailNo (Key from Detail=>DetailNo; but part of primary key fro OrderResult)
int ResultNo (Part of primary key; generated by program)
...
My Entities are defined as:
public Class Order
{
public int OrderNo { get; set; }
publice virtual ICollection<Detail> Details { get; set; }
}
public Class Detail
{
public int OrderNo { get; set; }
public int DetailNo { get; set; }
public virtual Order Order { get; set; }
public virtual ICollection<Result> Results { get; set; }
}
public Class Result
{
public int OrderNo { get; set; }
public int DetailNo { get; set; }
public int ResultNo { get; set; }
public virtual Detail Detail { get; set; }
}
So how would you define these key and associations using the fluent API? Currently I'm getting the OrderDetails linked to the Order correctly, but not getting the correct OrderResults.
You can try something like this:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Mapping for Order
modelBuilder.Entity<Order>()
.HasKey(o => o.OrderNo);
modelBuilder.Entity<Order>()
.Property(o => o.OrderNo)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
modelBuilder.Entity<Order>()
.HasMany(o => o.Details)
.WithRequired(d => d.Order)
.HasForeignKey(d => d.OrderNo);
// Mapping for Detail
modelBuilder.Entity<Detail>()
.HasKey(d => new { d.OrderNo, d.DetailNo });
// I believe, setting to DatabaseGeneratedOption.None is not necessary
// for composite keys
modelBuilder.Entity<Detail>()
.HasMany(d => d.Results)
.WithRequired(r => r.Detail)
.HasForeignKey(r => new { r.OrderNo, r.DetailNo });
// Mapping for Result
modelBuilder.Entity<Result>()
.HasKey(r => new { r.OrderNo, r.DetailNo, r.ResultNo });
}
Fluent API is quite verbose in this example. You can all the mappings also define with data annotations.