"Sequence contains more than one matching element" onload of any Kendo grid - asp.net-mvc

I know this issue has arisen many times on Stack Overflow. I've looked at them, but believe this to be unique:
I'm not using .Single() or .SingleOrDefault() in any LINQ expressions
I checked my models for duplicates, like "Id" and "ID", there are none
This happens onload of any Kendo UI MVC grids, on any table, on any page in my website that has such a grid, and we have several different pages, each with their own grids
Just some history, we just changed some foreign keys to Guids from IDs (ints) in order to point them at different tables in the database than they are currently in the code. Models were updated, accordingly. We also added a view for the Kendo grid to be pointed at, and this was changed in the view. But even grids that have nothing to do with the original or new SQL view/C# models seem to have been affected. Now, during this phase:
public OurDatabase(bool enableLazyLoading=true)
: base("name=OurDBContext")
{
Database.SetInitializer<OurDatabase>(null);
((IObjectContextAdapter)this).ObjectContext.ContextOptions.ProxyCreationEnabled = enableLazyLoading;
((IObjectContextAdapter)this).ObjectContext.ContextOptions.LazyLoadingEnabled = enableLazyLoading;
}
It keeps giving the error "Sequence contains more than one matching element". It will highlight on that middle line with that error.
Can something changing in the database cause this? Code that once worked, and hasn't been changed since that time, now does not, and this is very confusing.

I found out the answers to my problem. Yes, plural.
First, if I commented out the public virtual DbSet<blah> blah { get; set; } in the database entity, and everything that had anything to do with its model, the old code would work again. So that told me the issues were in the model. I also thought I could name "blah" whatever I wanted. I found it should be named after the DB or view name, instead, so I updated that, accordingly.
Second, I found out I had some major issues with my models, which I had used some decorations on with little knowledge behind them. Ex.
[Key]
[Column(name:"GUID", order:2)]
public Guid Guid
It was #2 because ID was #1, and if I put ID in just like above, I got a green squiggly under ID saying 'MyProject.Entities' hides inherited member 'MyProject.Entities.PersistedEntity<int>.Id'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.
That was because of the PersistedEntity<int> inherited class that had Id and Name in it, already, that a team member had added. I commented that out and declared the ID and Name columns (which also had the green squiggly until commenting out that class) the normal way.
Then I got an error on the composite keys, saying it could not order them (gee, I wonder why). So these are how they look, now:
[Key]
[Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ID { get; set;}
[Key]
[Column(Order = 1)]
public Guid GUID { get; set;}
[Key]
[Column(Order = 2)]
[StringLength(60)]
public string Name { get; set;}
Which set the ordering and composite key correctly, starting at 0 instead of 1 that I had previously. I had other columns, too, so I continued with setting the [Key] and [Column(Order = x)] attributes on those, too.
Third, I also added a decoration above the class, calling it a table, even though this was for a view (weird):
[Table("My.View")]
Keeping things commented out that relates to adding new models in the controllers seems to be the way to go to troubleshoot this lousy, non-descript error that for me said nothing about the real, underlying issues - at least in this instance. I also didn't think ALL of my grids would stop working just because I added a model - even ones that were not pointed at the new model or the one it was replacing.
After I got the models with the right annotations, I was able to uncomment out the DbSets in my main database model, and because my team member used "Id", when I re-generated the model, I needed to update the ID the grid was using in the Kendo view:
.DataSource(dataSource => dataSource
.Ajax()
.Model
{
.model.Id(p => p.ID)
})
Also, note, I was only able to get it fully working after upgrading to Entity Framework 6.1. Before then, I was getting "Invalid object name 'dbo.My.View'". Apparently in previous versions of EF, you can't just add a model for a table/view and expect it to find it.

Related

Dynamically change models and controllers after publishing website in ASP.NET Core MVC

I'm using ASP.NET Core MVC 2. I need to operator can change some elements of Models or view codes. How I can code or design for it.
For example: I have a "news" model and I want to operator (final user of website, who can't code or access to visual studio) can add this to "news" model:
public string ImageUrl { get; set; }
and also can change the database without coding.
Thanks
If you want to design a completely extensible model, you could use something called Entity–attribute–value model (EAV).
Your model might have a couple common attributes like Title and Summary. Then you might have a list of Custom Fields, the first of which could be ImageUrl. You could create your own class called CustomField or something similar, which would have properties such as FieldName, and DataType.
public string Title { get; set; }
public string Summary { get; set; }
public List<CustomField> CustomFields { get; set; }
You would then have a table full of custom field values and the tables they belong to. It gets pretty complex.
When you want to automatically reflect your model changes to the database, you will need an ORM framework like EF (Entity Framework). You can check more here.
In order for your case to happen is to build your own configuration platform that may use several tools and mechanincs that will allow you to generate code and then compile it. Such as T4 and more.
In general, this is a very hard task to accomplish and even big experienced teams would have troubles to build something similar.
I can not post any code, as this would only seem a desperate approach.

NHibernate mapping class with attribute of same type

I am new to the .NET MVC. However this "problem" I am stuck at looks pretty common, I cannot find any tutorial or stackoverflow thread that explains how to do it properly.
I have a class, MyClass which has two attributes of same type
public class MyClass : IEquatable<MyClass>
{
public virtual MyClass LeftChild { get; set; }
public virtual MyClass RightChild { get; set; }
...
}
Now I have problem with nhibernate mapping. At first I tried one-to-one mapping. I created new instance and DO NOT set Childs , persisted it (lets say Id=1), and pass this instance to View and I expected that RightChild will be NULL and LeftChild will be NULL. But in the debbug mode i can see, that the RightChild was set to MyClass with Id=1 (Like MyClass instance set itself to this attribute) and same with LeftChild.
Mapping MyClass.hbm.xml
...
<one-to-one name="LeftChild" class="MyClass"/>
<one-to-one name="RightChild" class="MyClass"/>
...
Is it right approach to do it with one-to-one or I should use something else ?
References, where our table contains foreign keys, are almost always best to map with many-to-one.
Simply think about it as a standard reference to other instance (Country, Currency)... which is accidentally of a same type.
<many-to-one name="LeftChild" column="LeftChild_ID" class="MyClass"/>
<many-to-one name="RightChild" column="RightChild_ID" class="MyClass"/>
The only challenge I see, is to be sure that the server part (C# code, app) will be properly setting these values. There is not bi-directional mapping in this kind of persisted information. Each sibling, needs its own information who is right who is left.
I mean, comparing with Similar mapping: parent-child (also same type). In that case we would have child having reference to parent, and parent having collection of children.
But that is not the same here.. again.. we map just one side of the relation.
A one-to-one is not suitable here, because it requires two tables, with (almost) the same amount of rows, sharing same column as a key... I like to use it, but for kind of Additional info... see:
NHibernate Dynamic Columns Number
NHibernate Optional Join generates insert instead of update

Real examples of using EF lazy loading in MVC application

Can anyone post correct and useful an example of using EF lazy loading in MVC application?
I've tried to research the question, but I can't get proper case.
As a result my conclusion is: since web apps are stateless there is no sense to include LL to entities. But it sounds strange. That's why the question is here.
Can you confirm or otherwise refute my conclusion?
EDIT
The statment "stateless" in question context is important in my mind. Let's pretend 2 scenarios. First one relates for example to WPF app and the second one to MVC. Let's suppose that thre is the next simple object:
public class Person
{
public int Age { get; set; }
public string Name { get; set; }
...
public virtual List<Activity> Activities { get; set; }
}
1) WPF. User is able to request the only Person without his Activities. Thus he get a small portion of data. Overhead are reasonable. At the same time user can decide to request person's activities.
Due to ll mechanism, EF simply loads activities without requesting person object again, since Person still exists in application (of course, if we code it in such a way).
2) MVC. The same actions are there. But the only difference that, after server response, all resources including object Person are disposes. And we can't load Person activities as we did in WPF application. We are forced to load Person again (overhead is increases comparing with WPF app)
The point is that Lazy loading can be executed only in the scope of the context to which the entity is attached - if you dispose the context you cannot use it.
I don't think you understand what lazy loading does, as it has nothing to do with whether there's any state or not. It's not like caching or something. Lazy loading is simply Entity Framework overloading a property to add a custom getter that issues a query to fetch the object or set of objects when the property is accessed for the first time.
For example, if you had something like:
public class Foo
{
public virtual Bar Bar { get; set; }
}
And you were to query a set of Foos from the database, the Bar property on all of them would be null, as EF would not have issued any queries yet to fetch the related Bar instance. However, if you were to iterate over this list of Foo and access some property on Bar (i.e. foo.Bar.Baz, then EF would issue a just-in-time query for the Bar instance, so that it could then return the Baz property on it.

Can I delete a single child entity without loading the entire collection?

I have 2 classes, like the below.
They can have very large collections - a Website may have 2,000+ WebsitePages and vice-versa.
class WebsitePage
{
public int ID {get;set;}
public string Title {get;set;}
public List<Website> Websites {get;set;}
}
class Website
{
public int ID {get;set;}
public string Title {get;set;}
public List<WebsitePage> WebsitePages {get;set;}
}
I am having trouble removing a WebsitePage from a Website. Particularly when removing a WebsitePage from mutliple Websites.
For example, I might have code like this:
var pageToRemove = db.WebsitePages.FirstOrDefault();
var websites = db.Websites.Include(i => i.WebsitePages).ToList();
foreach(var website in websites)
{
website.WebsitePages.Remove(pageToRemove)
}
If each website Include() 2k pages, you can imagine it takes ages to load that second line.
But if I don't Include() the WebsitePages when fetching the Websites, there is no child collection loaded for me to delete from.
I have tried to just Include() the pages that I need to delete, but of course when saving that gives me an empty collection.
Is there a recommended or better way to approach this?
I am working with an existing MVC site and I would rather not have to create an entity class for the join table unless absolutely necessary.
No, you can't... normally.
A many-to-many relationship (with a hidden junction table) can only be affected by adding/removing items in the nested collections. And for this the collections must be loaded.
But there are some options.
Option 1.
Delete data from the junction table by raw SQL. Basically this looks like
context.Database.ExecuteSqlCommand(
"DELETE FROM WebsiteWebsitePage WHERE WebsiteID = x AND WebsitePageID = y"));
(not using parameters).
Option 2.
Include the junction into the class model, i.e. map the junction table to a class WebsiteWebsitePage. Both Website and WebsitePage will now have
public ICollection<WebsiteWebsitePage> WebsiteWebsitePages { get; set; }
and WebsiteWebsitePage will have reference properties to both Website and WebsitePage. Now you can manipulate the junctions directly through the class model.
I consider this the best option, because everything happens the standard way of working with entities with validations and tracking and all. Also, chances are that sooner or later you will need an explicit junction class because you're going to want to add more data to it.
Option 3.
The box of tricks.
I tried to do this by removing a stub entity from the collection. In your case: create a WebsitePage object with a valid primary key value and remove it from Website.WebsitePages without loading the collection. But EF doesn't notice the change because it isn't tracking Website.WebsitePages, and the item is not in the collection to begin with.
But this made me realize I had to make EF track a Website.WebsitePages collection with 1 item in it and then remove that item. I got this working by first building the Website item and then attaching it to a new context. I'll show the code I used (a standard Product - Category model) to prevent typos.
Product prd;
// Step 1: build an object with 1 item in its collection
Category cat = new Category { Id = 3 }; // Stub entity
using(var db = new ProdCatContext())
{
db.Configuration.LazyLoadingEnabled = false;
prd = db.Products.First();
prd.Categories.Add(cat);
}
// Step 2: attach to a new context and remove the category.
using(var db = new ProdCatContext())
{
db.Configuration.LazyLoadingEnabled = false;
db.Products.Attach(prd);
prd.Categories.Remove(cat);
db.SaveChanges(); // Deletes the junction record.
}
Lazy loading is disabled, otherwise the Categories would still be loaded when prd.Categories is addressed.
My interpretation of what happens here is: In the second step, EF not only starts tracking the product when you attach it, but also its associations, because it 'knows' you can't load these associations yourself in a many to many relationship. It doesn't do this, however, when you add the category in the first step.

.SaveChanges() stores duplicates in entity framework

for ( int i = 0; i < libraryList.Count; i++)
{
if (ModelState.IsValid)
{
context.Library.Add(libraryList[i]);
context.SaveChanges();
}
}
A library contains an entity 'predefinedgoals' which is already set up in the DB. So when the above code runs it stores dublicates of 'predefinedgoals' and assigns new ID's to them.
I read that I should attach the existing entity to the context but I'm not sure how to to do it in my scenario. The classes look like this:
class library
int libraryID
list<book> bks
.
class book
int bookID
list<importantdates> impdts
.
class importantdate
int importantdateID
predefinedgoal predfg
int numberofresellers
.
class predefinedgoal
int predefinedgoalID
string description
int daysfrompublication
I tried something like this right after ModelState.IsValid but I sense I'm doing it wrong:
var prdfgs= context.predefinedgoals.ToList();
foreach(var pg in prdfgs)
context.predefinedgoals.Attach(pg);
This answer is going to be based on a couple of assumptions, but I've seen this exact problem so many times that this is automatically my go-to answer.
What I think you're doing is that you're creating Library, Book, and ImportantDate objects (and setting up all of the relationships between them as well). In the process of doing all of this, however, you are trying to set the PreDefinedGoal navigational property on those ImportantDate objects, all the while leaving the actual int FK property (that would be something like PreDefinedGoalID), still set to 0. When that happens, Entity Framework disregards the fact that the object contained in the navigational property has an ID on it, and assumes that you are trying to create this PreDefinedGoal object from scratch, just like you're creating the ImportantDate object (as well as the others). It will then create a PreDefinedGoal object with the exact same data as the one you're actually trying to use, but it will create it as a separate, duplicate record in the database.
The solution to your problem then is simple: Don't set the navigational property. Just simply set the FK (ImportantDate.PreDefinedGoalID) to the ID of the PreDefinedGoal object that you want to hook up to it. When you do that, and you save it, Entity Framework will then reach out to the database for the correct object based on that ID, and thus you will avoid having duplicate PreDefinedGoal objects in your database.
FYI: I learned this from one of Julie Lerman's MSDN posts. If you're going to be working with EF, I highly recommend reading her posts and columns.
I am in the same situation and found a workaround. The way this workaround works makes me think that in this case EF is to blame for handling the situation badly.
In order to simplify the example I will just post an example with one object and it's navigational property.
public class Topic
{
int Id { get; set; }
public String Name { get; set; }
public String Description { get; set; }
}
public class Course
{
int Id { get; set; }
public Topic Topic { get; set; }
// additional properties don't matter now
}
Note the absence of any foreign key or other data annotations. EF6 will correctly create the database schema from this and infer that Id is the primary key.
Without workaround adding a new course for an existing topic will create a new topic object with a new Id (overwriting the Id it was given!) :
db.Courses.Add(course);
await db.SaveChangesAsync();
The braindead workaround:
course.topic = db.Topics.Find(course.topic.Id);
db.Courses.Add(course);
await db.SaveChangesAsync();
In other words, if the topic has been loaded from the context directly, EF will recognize it as an existing topic and don't try to add it again.
Update: To just attach the entity without reloading it:
db.Topics.Attach(course.topic);
However you will run into more issues with this setup, it is probably best to use ForeignKey attribute(s) and include the TopicId in Course object. Following works OK but still looks ridiculous to me:
[ForeignKey("Topic")]
public int TopicId { get; set; }
[ForeignKey("TopicId")]
public virtual Topic Topic { get; set; }
Would love to hear about a less redundant solution though.
The answer to why it stored duplicates in my scenario was that I performed tasks in two different classes - using different database context variables in each of them.
So class #1 is the one in my question, that's where I'm saving to the DB using context #1. In class #2 I retrieved all the PredefinedGoals and added them to ImportantDates but to do this I created context #2. The ID's and objects were the same but retrieved from different context variables.
I solved it by retrieving the PredefinedGoals in class #1 with context variable #1 and sent them as an argument to class #2.

Resources