I'm querying my database using EF DB first and i have my "news" area that is linked to several other areas and i don't want to load the relationships of this object. What options do i have to do it ? I'm working with WebApi 2 and returning the data as JSON to my application.
I know some options that i have tried:
Create a second class with the fields i want and map it using the LINQ select;
Remove them manually setting them as null.
I don't really like those options because the second one doesn't sounds right and the first one feels like redoing work and i was wondering if there's a better option to solve this.
Your options here are probably:
Make DTOs specific for your "news" area, that will contain only information, that you need to return, use some kind of Mapper to map from your Entity to your DTO. I would recommend that method as it gives you enough flexibility to make your API contract and DB Schema not depend on each other heavily.
Disable Lazy-loading either system-wide or for this specific relationship removing virtual keyword and using .Include(x=>x.Navigation) where you explicitely need those properties.
Make sure to turn off Lazy Loading
this.Configuration.LazyLoadingEnabled = false;
and turn off Proxy Creation
this.Configuration.ContextOptions.ProxyCreationEnabled = false;
Then make sure NOT to use an Include in your LINQ query. HTH
Related
I want to persist a linked list of objects using in my ASP.Net Core application. For simplicity, I'll use blog and comments; although the real context is much more complex.
I scaffolded two tables, and changed ICollection<Comment> to LinkedList<Comment>. However, if I create an initial migration and apply to an empty database, I don't get anything "linked" in the database (no next or previous). Also, if I seed the data, and then do something like this:
var comments = _context.blogs.First().Comments
I get null. If I leave public virtual ICollection<Comment> Comments, I get the IEnumerable just fine.
I tried to use LinkedList<LinkedListNode<Comment>> instead, and it works nice unless I try to create a migration. Getting an error
No suitable constructor found for entity type 'LinkedListNode'. The following constructors had parameters that could not be bound to properties of the entity type: cannot bind 'value' in 'LinkedListNode(Comment value)'; cannot bind 'list', 'value' in 'LinkedListNode(LinkedList list, Comment value)'.
I couldn't find any guidance how to implement LinkedList in C#/.NET Core (obviously, I can do it manually, having next and prev fields - but I would very much prefer to use framework capabilities, if possible!)
I don't know much about MS SQL server, but the whole next and prev parts in mysql won't work because you can't map the keys it would require to track the fields properly because each link has to have an id in a database to link to. only thing I know of would be create the next/prev yourself and use some custom data persistence or data annotations. but the foreign key constraints I'm pretty sure on any relational database will prevent you from auto persisting those types of fields. reason being tracking deletes, inserts etc would be a nightmare because if you remove the middle of the chain, then the database has to try and guess where to link the ends to
I am currently programming game which is using C# connected with Entity Framework.
I have a lot of relationships with tables which are main models used in game. Because of that i have to use a lot of navigational properties of those models.
When i create my viewModel i have code similar to this :
Avatar = new ImageViewModel(company.Entity.ImgUrl);
CountryName = company.Region.Country.Entity.Name;
RegionName = company.Region.Name;
Name = company.Entity.Name;
Money = MoneyViewModel.GetMoney(company.Entity.Wallet);
OwnerName = company.Owner.Name;
OwnerID = company.OwnerID;
Naturally it ends up firing multiple queries when i want to access navigational proprties.
I addressed this problem by using Include in my Controller before passing model to the view model constructor.
this is heavily consuming my time because in the end i need to recursively check which navigational properties are needed in my view models and include them manualy in first query.
My question is :
Is this code design apropriate? If not then what is correct approach to this kind of problem?
Personally i feel that it will be cumbersome in long term.
As long as you have eager loading selected You have to manually include what you need. This is the price you pay for performance.
I would approach this in a different way. I would create Views and stored procedure that would give me the desired data fields, and then use Automapper to transfer the values directly into DTO classes.
This is usually what I do, and it pays off. I get the performance, but also keep everything very simple and maintainable.
As long as you're using eager loading, you need to manually include all the needed nested navigation properties. But that costs the better preformance.
So, if you have repetitive queries in diffrenet places in your code, which include the same navigational properties, you can facilitate your job by extracting them in extension method. Check the answer in Entity Framework - Is there a way to automatically eager-load child entities without Include()?, which shows an appropriate example how to do that.
Excuse me for my broken English.
In my application, all objects in the context have a property called ObsoleteFlag, which basically means if the object should still be used on the frontend. It's some sort of "soft-delete" flag without actually having to delete the data.
Now I want to prevent EF from returning any object where ObsoleteFlag is set to true (1)
If for example I retrieve object X, the navigational list property Y contains all the related objects of type Y, no matter what the ObsoleteFlag is set to.
Is there some general way of preventing EF from doing this? I don't want to check on the ObsoleteFlag property everywhere I access the context, and for every navigational property that may be loaded too.
Thanks and sorry for my broken English.
Two different approaches:
In your repository layer have a GetAllWhatever() that returns IQueryable<Whatever> and uses Where(x => !x.Obsolete) and use this whenever you retrieve objects of this type.
Create a view of Create View ActiveWhatever As Select * from ActiveWhatever Where obsolete = 0 and bind to that rather than the table.
The first is essentially checking the flag every time, but doing so in one place, so you don't have to keep thinking about it.
The second is much the same, but the work is pushed to the database instead of the .NET code. If you are going to modify the entities or add new entities you will have to make it a modifiable view, but just how that is done depends on the database in question (e.g. you can do it with triggers in SQL Server, and triggers or rules in PostgreSQL).
The second can also include having a rule or trigger for DELETE that sets your obsolete property instead of deleting, so that a normal delete as far as Entity Framework is concerned becomes one of your soft-deletes as far as the database is concerned.
I'd go for that approach unless you had a reason to object to a view existing just to help the application's implementation (that is you're heavily into the database being "pure" in being concerned with the data rather than its use). But then, if it's handy for one application it's likely handy for more, given the very meaning of this "obsolete".
I'm getting the following error when trying to run a solution using Entity Framework 4.0 and am wondering how to change the mapping settings to correct it:
Problem in mapping fragments starting at line 588: Must specify mapping for all key properties (UserDatas.Id) of the EntitySet UserDatas
To give some background - I originally created the tables shown below with Modified/Created Date/By and Id columns in each of them, but then decided to pull them out into the abstract UserData and then use inheritance instead. Since I changed this it's all gone to pot!
Does anyone have any pointers as to where I'm going wrong? I've been using the design view show below (the GUI) and it feels like I've hit a brick wall.
My db.edmx design view looks like this, and clicking on the error takes me to the Variables table shown below, but the error is repeated for all the other tables that inherit this Id (please ignore all the links to other tables - I didn't want to post the whole big db schematic):
Many thanks.
Sounds like you are mis-using OO inheritance here. Just because objects share items with the same property names doesn't mean that they Inherit from the base. For example, ask yourself in your modle if Tag IS A UserData? I suspect you could phrase this better that Tag HAS A UserData which points to containment rather than inheritance. I would recommend setting up a common IUserData interface where each object implements the interface distinctly. In that case, your mapping then would move the properties for the UserData interface back into the underlying classes (as they were configured originally). While you may be able to get your mapping to work with the inheritance model, your queries will get significantly complex both from a LINQ and TSQL perspective.
I have a Linq-To-Sql based repository class which I have been successfully using. I am adding some functionality to the solution, which will provide WCF based access to the database.
I have not exposed the generated Linq classes as DataContracts, I've instead created my own "ViewModel" as a POCO for each entity I am going to be returning.
My question is, in order to do updates and take advantage of some of the Linq-To-Sql features like cyclic references from within my Service, do I need to add a Rowversion/Timestamp field to each table in by database so I can use code like dc.Table.Attach(myDisconnectedObject)? The alternitive, seems ugly:
var updateModel = dc.Table.SingleOrDefault(t => t.ID == myDisconnectedObject.ID);
updateModel.PropertyA = myDisconnectedObject.PropertyA;
updateModel.PropertyB = myDisconnectedObject.PropertyB;
updateModel.PropertyC = myDisconnectedObject.PropertyC;
// and so on and so forth
dc.SubmitChanges();
I guess a RowVersion/TimeStamp column on each table might be the best and least intrusive option - just basically check for that one value, and you're sure whether or not your data might have been modified in the mean time. All other columns can be set to Update Check=Never. This will take care of handling the possible concurrency issues when updating your database from "returning" objects.
However, the other thing you should definitely check out is AutoMapper - it's a great little component to ease those left-right-assignment orgies you have to go through when using ViewModels / Data Transfer Objects by making this mapping between two object types a snap. It's well used, well tested, used by many and very stable - a winner!