Error "EntityType has no key defined" for composite keys - ef-code-first

I am trying to bind my data using entity framework v6.1.3 but I am getting this error message EntityType has no key defined. Define the key for this EntityType. (I am having a composite key)
I've tried the following approaches:
public class CommunicationCollection
{
[Key, Column(Order = 0)]
[ForeignKey("FK_CommunicationCollection_Communication")]
public Guid CommunicationId;
[Key, Column(Order = 1)]
[ForeignKey("FK_CommunicationCollection_Collection")]
public Guid CollectionId;
}
and this
public class CommunicationCollection
{
[Key, Column(Order = 0)]
[ForeignKey("FK_CommunicationCollection_Communication")]
public Guid CommunicationId;
[Key, Column(Order = 1)]
[ForeignKey("FK_CommunicationCollection_Collection")]
public Guid CollectionId;
public virtual Communication Communication { get; set; }
public virtual Collection Collection { get; set; }
}
and also this
public class CommunicationCollection
{
[Key, Column(Order = 0)]
public Guid CommunicationId;
[Key, Column(Order = 1)]
public Guid CollectionId;
}
and in the DB I have
CREATE TABLE [CommunicationCollection](
[CommunicationId] [uniqueidentifier] NOT NULL,
[CollectionId] [uniqueidentifier] NOT NULL,
CONSTRAINT [PK_CommunicationCollection] PRIMARY KEY CLUSTERED
(
[CommunicationId] ASC,
[CollectionId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [CommunicationCollection] WITH CHECK ADD CONSTRAINT [FK_CommunicationCollection_Collection] FOREIGN KEY([CollectionId])
REFERENCES [Collection] ([CollectionId])
GO
ALTER TABLE [CommunicationCollection] CHECK CONSTRAINT [FK_CommunicationCollection_Collection]
GO
ALTER TABLE [CommunicationCollection] WITH CHECK ADD CONSTRAINT [FK_CommunicationCollection_Communication] FOREIGN KEY([CommunicationId])
REFERENCES [Communication] ([CommunicationId])
GO
ALTER TABLE [CommunicationCollection] CHECK CONSTRAINT [FK_CommunicationCollection_Communication]
GO
Any idea what am I missing?
Thanks a lot!

With EF, everything needs to be properties and not just 'plain' variables. This is needed so EF can hook into those methods.
So like this:
public Guid CommunicationId { get; set; }
public Guid CollectionId { get; set; }
Forgetting to do this causes all kinds of problems that can be hard to trace back to the actual cause, as you have just encountered.

Related

Linq2db create table with DateTime2(3) fails when using in memory db and SQLiteDataProvider

I am trying to create table in memory db using Linq2Db, and SQLiteDataProvider in a netcore3.1 application.
And if mapping class has a property with attribute
[Column(DataType=DataType.DateTime2, Precision=3), Nullable ]
it gives me the following syntax error :
Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 1: 'near ")": syntax error'.
I dig for the query it generates and its this:
CREATE TABLE [testTable]
(
[Id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
[Created] DateTime2(3, ) NULL
)
Here is an example that I'm trying:
using System;
using LinqToDB;
using LinqToDB.Data;
using LinqToDB.Mapping;
namespace InMemoryDb
{
class Program
{
static void Main(string[] args)
{
DataConnection.AddConfiguration("default", "Data Source=Sharable;Mode=Memory;Cache=Shared",
new LinqToDB.DataProvider.SQLite.SQLiteDataProvider("SQLite.MS"));
DataConnection.DefaultConfiguration = "default";
using var db = new DataConnection("default");
db.CreateTable<TestTable>();
}
[Table(Schema="dbo", Name="testTable")]
public class TestTable
{
[Column(DataType=DataType.Int32), PrimaryKey, Identity]
public int Id { get; set; }
[Column(DataType=DataType.DateTime2, Precision=3), Nullable]
public DateTime? Created { get; set; }
}
}
}
why its generates query with DateTime2(3, ) and not a correct one DateTime2(3)?
Try this as workaround
[Column(DbType="DateTime2(3)", Nullable ]
You can use possibility of linq2db to define schema for several databases.
Note that there is no DateTime type in SQLite.
[Table(Schema="dbo", Name="testTable")]
public class TestTable
{
[Column(DataType=DataType.Int32), PrimaryKey, Identity]
public int Id { get; set; }
[Column(Configuration=ProviderName.SQLite, DataType=DataType.DateTime2), Nullable]
[Column(DataType=DataType.DateTime2, Precision=3), Nullable]
public DateTime? Created { get; set; }
}

Android table creation Failure (while compiling: CREATE TABLE IF NOT EXISTS

While compiling:
CREATE TABLE IF NOT EXISTS `SeasonMasterDB`
(`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`id` TEXT PRIMARY KEY AUTOINCREMENT, `name` TEXT
);
that is why you are getting an error. Please help me, this is my code:
#Table(name = "SeasonMasterDB",database = AppDatabase.class)`enter code here`
public class SeasonMasterDB extends Model {
#PrimaryKey
public Long id;
#Column(name = "id")
public String idValue;
#Column(name = "name")
public String name;
public SeasonMasterDB()
{
}
public SeasonMasterDB(String name,String id)
{
this.idValue = id;
this.name = name;
}
}
You cannot have two columns with the same name. Rename one of your id columns.

Cannot insert the value NULL into column error

I am attempting to save user preferences into a table but am getting a null exception and I do not understand why. This is an MVC 4 application and this is my action result where I am getting the error.
public ActionResult Go(string path, string name)
{
RaterContext r = new RaterContext();
UserData u = new UserData();
var userid = u.GetCurrentUserData().UserId;
var info = r.RatersInfo.Where(w => w.RaterName.Equals(name)).FirstOrDefault();
var pref = r.RatersPreferences.Where(w => w.RaterId.Equals(info.RaterId) && w.UserId.Equals(userid)).FirstOrDefault();
if (pref != null && pref.Count > 0)
{
pref.Count++;
r.SaveChanges();
}
else
{
pref = new RaterPreferences();
pref.UserId = userid;
pref.RaterId = info.RaterId;
pref.Count = 1;
r.RatersPreferences.Add(pref);
r.SaveChanges();
}
return Redirect(path);
}
There is nothing saved in the preferences table yet so it is hitting the else block and throwing a null exception on r.SaveChanges();. The exception is
Cannot insert the value NULL into column 'UserId', table
'WebSiteNew.dbo.RaterPreferences'; column does not allow nulls. INSERT
fails.\r\nThe statement has been terminated.
The reason this doesn't make sense is because all three properties, including the UserId have data when I step through. These are the only fields in the table. UserId = 1, RaterId = 6 and Count is clearly set to 1. They are all set as non-nullable ints and the primary key is a combination of UserId and RaterId. My Model is as follows.
public class RaterContext : DbContext
{
public RaterContext()
: base("DefaultConnection")
{
}
public DbSet<RaterInfo> RatersInfo { get; set; }
public DbSet<RaterPreferences> RatersPreferences { get; set; }
}
[Table("RaterInfo")]
public class RaterInfo
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int RaterId { get; set; }
public string RaterName { get; set; }
public string RaterLink { get; set; }
public string Section { get; set; }
public string Department { get; set; }
}
[Table("RaterPreferences")]
public class RaterPreferences
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public int RaterId { get; set; }
public int Count { get; set; }
}
Any help would be greatly appreciated as I am relatively new to MVC and ASP.NET. Let me know if you need more information. Thanks in advance!
I don't know if this helps but I tested to see what would happen on UPDATE by adding data manually so it would catch on the if block and that works. I'm only getting an error on INSERT.
Here is the create statement for the table in question.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[RaterPreferences](
[UserId] [int] NOT NULL,
[RaterId] [int] NOT NULL,
[Count] [int] NOT NULL,
PRIMARY KEY CLUSTERED
(
[UserId] ASC,
[RaterId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[RaterPreferences] WITH CHECK ADD CONSTRAINT [FK_RaterPreferences_RaterInfo] FOREIGN KEY([RaterId])
REFERENCES [dbo].[RaterInfo] ([RaterId])
GO
ALTER TABLE [dbo].[RaterPreferences] CHECK CONSTRAINT [FK_RaterPreferences_RaterInfo]
GO
I have copied your code into a brand new ASP.Net MVC project with the current version of Entity Framework and I am able to run your code with no problems. I escaped the UserData acquisition with code that looks like:
RaterContext r = new RaterContext();
//UserData u = new UserData();
var userid = 1; // u.GetCurrentUserData().UserId;
var info = r.RatersInfo.Where(w => w.RaterName.Equals(name)).FirstOrDefault();
and did not have a problem running the remainder of this code.
I think you may have some problems with your keys and database structure for the RaterPreferences table. I don't know your full data-model, but I don't understand how this fits in, and it is not keyed in your code the way that you describe.
Edit:
I've modified my database tables to reflect the design you've described. You have a difference between your EntityFramework code-first implementation and your database. It looks like your database existed first, and I would remove your EntityFramework classes and rebuild them with Database First techniques.

How to create database and table in sqlite programatically using monotouch?

Can any body help me about, how to create simple database and tables programatically and insert values ,step by step procedure in sqlite using monotouch.I am new to this technology .
Thank you..
If you're using sqlite-net (which I highly recommend) you can simply call:
Model
public class Stock
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
[MaxLength(8)]
public string Symbol { get; set; }
}
Create
var db = new SQLiteConnection("stocks.db");
db.CreateTable<Stock>();
Insert
var s = db.Insert(new Stock() {
Symbol = symbol });
Query
return db.Query ("select * from Valuation where StockId = ?", stock.Id);

Entity framework 4 with ctp5 and dirty generated sql

I have a problem with strange generated SQL in ef4 ctp5.
I have simple model with mapping :
[Table("post_auction")]
public class PostAuction
{
[Key,Column(Name="Id"),DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGenerationOption.Identity)]
public int Id { get; set; }
[Column(Name = "Number")]
public int Number { get; set; }
[Column(Name = "Label")]
public string Label { get; set; }
[Column(Name = "Description")]
public string Description { get; set; }
[Column(Name = "CategoryId")]
public int PostAuctionCategoryId { get; set; }
[Column(Name = "PriceCZK")]
public int PriceCZK { get; set; }
[NotMapped]
public bool IsAuctionPhotoExitst
{
get
{
if (File.Exists(HttpContext.Current.Server.MapPath("~/Public/Images/Posts/Thumbs/small_" + this.Number + ".jpg")))
return true;
return false;
}
}
}
and my linq query is :
_rovastampDbContext.PostAuctions.Where(x => x.PostAuctionCategoryId == auctionId).OrderBy(x => x.Id).ToList();
Ef4 profiler shows me
SELECT
[Project1].[Id] AS [Id],
[Project1].[Number] AS [Number],
[Project1].[Label] AS [Label],
[Project1].[Description] AS [Description],
[Project1].[CategoryId] AS [CategoryId],
[Project1].[PriceCZK] AS [PriceCZK]
FROM
(SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Number] AS [Number],
[Extent1].[Label] AS [Label],
[Extent1].[Description] AS [Description],
[Extent1].[CategoryId] AS [CategoryId],
[Extent1].[PriceCZK] AS [PriceCZK]
FROM
[dbo].[post_auction] AS [Extent1]
WHERE
[Extent1].[CategoryId] = 1 /* #p__linq__0 */) AS [Project1]
ORDER BY
[Project1].[Id] ASC
My question is a pretty simple : Why ef4 generate that complicated query, when right one is
SELECT ...
FROM TABLE
WHERE CategoryId = 1
ORDER BY Id ASC
Thanks for your advice :)
Martin
EDIT : If I let EF to create db automatic, the problem with query persists...
Excellent question. I'm guessing that it's a bug, since my (edmx-generated) Entity Framework context doesn't produce a projection the way yours does. I would report it as a bug.
Yeah for sure, looks like Beta-garbled code gen to me. I just tried it too with LINQ-SQL, nothing similar. Be sure to report it!

Resources