Need help using entities for ASP.NET MVC 2 framework - c#

I'm making a site in ASP.NET MVC 2 using C#. I designed a database with a bunch of tables that have many to many relationships, similar to the following:
GrandParent - many to many - Parent
and
Parent - many to many - Child
I used the Entity Framework to make all of the entities class and am now working on a function in a repository class which adds a GrandParent.
It tries to create Child, add it to a Parent, then add the parent to a GrandParent and then add the GrandParent to the database by using the command
entities.GrandParents.AddObject(newGrandParent);
entities.SaveChanges();
It crashes on the SaveChanges() line with the error:
Unable to update the EntitySet
'JunctionPartentsChilds' because it
has a DefiningQuery and no
element exists in the
ModificationFunctionMapping element to
support the current operation.
EDIT:
I can fix that error by deleting all of the DefiningQuery elements in the auto generated code and now I'm getting an error on the same line that should be more descriptive but I'm still at a loss.
The error is: Invalid object name 'JunctionPartentsChilds' and it throws a UpdatingException.
Any ideas what's going wrong? Do you have to add to the database in a special order because of the many to many relationships?
Thanks!!

If you copy/pasted this error:
Invalid object name 'JunctionPartentsChilds'
Maybe the problem is the misspelling of "Parents" in the junction table name

Your description looks like to one to many relationsships. But anyway, please post your code fragment here, to see if there's an error in your statements.
Bye Thomas
P.S. Ther's a wonderful way to format your code like this
This is a line of code
if you klick the button with the 101

make sure that GrandParents table as a primarykey(identity) and rebuild the model

Related

Random InvalidCastException using ToListAsync on subclass objects

Context
I am using Entity Framework Core, SQLite and its spellfix1 extension.
There are two classes: MetaMovie and FuzzyMetaMovie
FuzzyMetaMovie is a subclass of MetaMovie
Description
At first, I get an IQueryable<MetaMovie> correspondingMovies using db.MetaMovies.Where(...). If no result, then I use db.FuzzyMetaMovies.FromRawSql(...) that is assigned to the same variable of type IQueryable<MetaMovie>. To finish, I call List<MetaMovie> tempList = await correspondingMovies.ToListAsync();.
Issue
The issue is coming from that last line. I am sometimes, rarelly, getting an InvalidCastException: Unable to cast object of type 'Castle.Proxies.MetaMovieProxy' to type 'com.cyberinternauts.all.MediaRecognizer.Models.Metas.FuzzyMetaMovie'.
I, then, tried calling the code with one of those specifically failing. No issue!! Any of the ones failing tried alone aren't creating the issue. So, I mean here it goes exactly through the same code path and the exception is not thrown.
I sincerely have no idea why is this happening. I know, you have no working code here. But, I am not able to circumvent the issue, thus no easy way to reproduce it.
Any idea?
Edit #1
I wrote a patch solution that does the trick (see my solution below). Though, I will explain how to reproduce it:
Context
Having two classes one is the child of the other: A being the parent of B.
The classes share the same table with a Discriminator column.
AsNoTracking() is not used.
Steps
Make a query that loads an object A with Id == 1
Make another query that loads an object B with Id ==1
Underlying reason of the crash
It is caused by EntityFramework that tries to load an entity of type B that has already been cached as type A. Thus, the downcasting failure from A to B.
The issue was coming from a previous call that loads at least one of the movies that is fetched by the raw query.
To fix it, I used (so no cache is used):
List<MetaMovie> tempList = await correspondingMovies.AsNoTracking().ToListAsync();
I opened an issue in GitHub for the efcore project: https://github.com/dotnet/efcore/issues/27802

Polymorphic cross-associations on Entity Framework

OK, this is an interesting and most importably real urgent problem for me to solve... In order for others to neatly comprehend it, I've stretched myself to make a well illustrated post.
The Object Model
So I have this simple, easy and "beautiful" model in mind. See the first picture. (You can ignore PathEntry, it's not relevant in my situation.)
The idea is that a MediaFeedItem owns:
a collection of ThumbnailFileEntries (accesible through the ThumbnailFiles property)
at most 1 raw FileEntry (MetadataFile property) and
at most 1 MediaFileEntry (MediaFile property)
We shall refer to these last three entity types as the file entities.
Now there's more: As you can see, I am inheriting both ThumbnailFileEntry and MediaFileEntry from FileEntry, and let's not debate that! (for now), it's one of those end-of-story aspects of the design and both entity types will continue to grow later on.
This already brings me some significant issues right away in regards to the polymorphic associations induced by the relationships from the file entities to MediaFeedItem.
The first thing that you shall observe is that I have eliminated the navigation property from the derived file entities (ThumbnailFileEntry and MediaFileEntry) to the primary entity MediaFeedItem.
I do this because they already inherit that property defined in the base class FileEntry. As you can see, I do not delete the roles at the end of these associations.
The Relational Model
I shall be using the so-vastly-conceptually-superior TPT strategy for generating and mapping my Object Model to the RDB world (vs TPH/TPC).
I'm using EF5-rc, the EDMX model designer to design my model, and the EF5 DbContext Generator to generate a DbContext and POCOs cuz I wanna use the DbContext API.
As you can see, I can nicely generate the database model using the EF tools:
The Problem
When loading a new MediaFeedItem and saving it, I get the following error:
System.InvalidOperationException: Multicplicity constraint violated. The role 'MetadataFile' of the relationship 'MediaFeedModel.MediaFeedItem_MetadataFile' has multiplicity 1 or 0..1.
What am I doing wrong?
Looking at your problem one thing stands out, The FK relationship between File and MediaFeedItem is required (IE a file must have a MediaFeedItem), but in the case where you are in an extended version of File you probably dont want this.
What i think you want to do is one of the following:
change the multiplicity on MediaFeedItem_FileEntry to 0..1 - 0..1 so that it isnt required at either end
create a new extended type to handle your metadataFile type and remove the direct reference between the base type and MediaFeedItem
I personally think the second is a more elegant solution to your problem as its creating an actual type for your MetadataFile
What appears to be happening is that you are trying to create an extended type but the base type isnt actually a metadata file.

Invalid object name 'dbo.TableName' when retrieving data from generated table

I'm using entity framework code first to create my tables. Please note - create the tables, not the DB, since I'm working on a hosted environment and I don't have a user that is allowed to create db's.
Committing a DB update works fine, but retrieving data gives the exception:
Exception Details: System.Data.SqlClient.SqlException: Invalid object name 'dbo.EventHosts'.
I've read that it happens because I'm not using EF Code First to create the DB. That's fine, but how do I elegantly solve this?
All the generated tables do not have a prefix like dbo. A solution like this doesn't work, and isn't elegant at all:
[Table("EventHosts", Schema = "")]
Ok, for me issue was that I had a table called dbo.UserState and in C# EF was trying to access dbo.UserStates because of pluralization.
The solution was to put Table attribute above class and specify the exact table name:
[Table("UserState")]
public class UserState
{
[Key]
public int UserId { get; set; }
}
To answer your first question: use the schema created for you by your hosting provider.
To answer your second question: No there is currently no direct way to change the default schema globally because you cannot modify existing conventions or create new conventions. You can try to hack it.
For example you can override OnModelCreating and use reflection to get all DbSet<> properties declared in your context. Than you can just use simple loop on these properties and create ToTable mapping call with name of the property as table name and your custom schema. It will require some playing with reflection to make this work.
Alternatively you can try to do some reusable approach by implementing custom conventions. You can find many different articles about using your own conventions with EF. Some examples:
Custom Conventions in Entity Framework Code First v 4.1
Conventions in Entity Framework 4.1 Final
My high level untested idea is following same principle and create assembly level attribute which will be processed by the convention mechanism and applied on all your entities.
Try to set default schema name to 'dbo' in SQL SERVER.
http://msdn.microsoft.com/en-us/library/ms173423.aspx
On of the reason for this error is the table named "EventHosts" may not Exist or that table is renamed to some other name please check with that..
https://stackoverflow.com/a/12808316/3069271
I had same issue, it was pluralize problem between mapping and db.

Cryptic Linq to Entities message

I get the following message:
{"Entities in 'Entities.ApprovalRequests' participate in the 'FK_ApprovalRequest_Audit' relationship. 0 related 'Audit' were found. 1 'Audit' is expected."}
I'm stumped, does anyone know what to make of it?
My EDMX had the FK and is correct, yet every time I get this message.
How one would go to debug this, would be most useful.
You probably tried to persist an entity of type ApprovalRequests with no associated entity of type Audit while your entity model specifies that each ApprovalRequests must have (at least) one Audit.

LINQ to SQL Basic insert throws: Attach or Add not new entity related exception

I am trying to insert a record. This code worked but has stopped working I don't know why. Here is the code:
using (SAASDataContext dc = new SAASDataContext())
{
tblAssessment a2 = new tblAssessment();
a2.AssessmentCentreId = centreId;
a2.AttemptNumber = 1;
dc.tblAssessments.InsertOnSubmit(a2);
dc.SubmitChanges();
CurrentAssessmentId = a2.AssessmentId;
}
The code compiles but throws the exception below on the dc.SubmitChanges(); line.
Exception thrown:
An attempt has been made to Attach or Add an entity that is not new,
perhaps having been loaded from another DataContext. This is not
supported.
Notes:
AssessmentCentreId is a foreign key on tblCentre, centreId is a valid existing centre id,
AssessmentCentreId and AttemptNumber are the only not null fields all other columns allow nulls.
I have googled but all the results seem to pertain to people trying to attach entities pulled from other disconnected DataContext's I'm not doing that so I'm stumped.
UPDATE:
Adding
dc.DeferredLoadingEnabled = false;
at the top of the using block makes it work, but I'd like to know why coz I have no idea at the moment sufficiently advanced technology being indistinguishable from magic right now :)
This was bugging me as well. I did some searching and found a lot of confusion and some sloppy work-arounds regarding detached entities. I then found a nice solution on codeplex that has solved the immediate issue and has greatly extended linq2sql functionality. Its a small class thats really easy to implement and forms an EntityBase for your projects dbml's.
Here is the offical description and link.
LINQ to SQL Entity Base is a simple base class that is primarily designed to support LINQ to SQL in a disconnected way, which is one of the shortcomings of the LINQ to SQL technology at the present time. This is highly useful in an n-Tier, distributed or ASP.NET environment where disconnected functionality is relavent.
http://linq2sqleb.codeplex.com/
Hope this helps anyone who is having similar.
Jerome Vernon
The issue is that the Centre object doesn't exist in the context. It's in the db, but not "in your hand" with a2. Try this:
a2.AssessmentCentre = dc.AssessmentCentres.SingleOrDefault(
d=>d.AssessmentCentreId.Equals(centreId));
The AssessmentCentre object will then exist in the context, which means there will be no problem with attaching it to a2.
If these are the only non-null columns, where is the primary key? LINQ to SQL requires a primary key to insert data. If you're using AssessmentCentreId on its own or along with AttemptNumber as a composite, are you sure you're not trying to insert a duplicate key?

Categories

Resources