Entity Framework: subset entity of larger entity - c#

Sooo basically I have a table called Comment. On that table I have three fields,
ID
Title
Text
I've created an Entity object for the table already and it maps all three fields, but what I want now is another Entity called CommentHeader that will map only ID and Title. I want to only load the titles of all the comments and not the text for speed reasons. So what's the best way for going about this?
I'm not looking for a Select statement with a var object. I can figure that one out on my own and I really don't like that solution because I'd much rather abstract it behind an Entity object.
I've tried the obvious solution, which was to just copy the original Entity object and delete Text from it. That resulted in an error because only one Entity can map to one table without conditions. It sounds to me like I have no choice but to use a Select statement. I just wanted to make sure before I did something stupid.
(By the way this example only has three fields for simplicity's sake. Assume that the header could have considerably more fields in it. This is the primary reason I don't want to just use a select with a var object, because it's not just one field but could be a whole bunch of fields).

The easiest way probably would be to create a view ("CommentHeaders") in the database that only selects ID and title from the Comment table. Then update your model and add the view, which will create a new entity based on those columns.

Related

DbContext with read-only set properties

I was reading this article http://blogs.msdn.com/b/adonet/archive/2011/01/27/using-dbcontext-in-ef-feature-ctp5-part-2-connections-and-models.aspx and was trying to figure out how to create private setters (the section in the article DbContext with read-only set properties is right before the summary). How would you create private setters? I was playing around with different methods but nothing seemed to work. I am doing this because I need to group the original table based on a query I have because the original table is a heap and I need a primary key for the entity. So anytime a client asks for this table it is already grouped. Not even sure if this is the correct way to do that. Thanks.
EDIT: sorry for being vague. I am doing code first. For example there exists a SQL Table with JobNbr, Qty and Date and I need to group by JobNumber, sum on Qty and take the oldest expiration date, and that will be my entity since this table has no primary key. The way I am doing it now gives me the error below from a method I created in the DbContext class. I do have a EntityTypeConfiguration class. Do I do this in that class?
EDIT: : you might be wondering why I am doing this. Basically I need to get data from the heap and save it in another database. My original approach was database.SqlQuery() to get grouped rows from the heap, but sometimes I have too many parameters for execute_sql. So I decided to create an entity for the grouped query without tracking changes (since all I am doing is reading from the table and saving to another DB). See my post here with the issue I am having https://stackoverflow.com/questions/22106030/entity-framework-6-this-database-sqlquery-character-limitation-with-sp-executes. The only way I know to get around it is to create an entity (even though in this case the entity is a query and not a table).
The entity or complex type
' cannot be
constructed in a LINQ to Entities query.

Oracle View base on a PIVOT query not null values

When creating a View based on a PIVOT query all the view fields become NULLABLE in the view metadata, is there any way to make them NOT NULLABLE?
I'm using the NVL function in the pivoted fields I need to be NOT NULL but they still become NULLABLE.
This is a problem to me because I'm using MS Entity Framework and it won't update the model based on tables or views without NOT NULLABLE columns.
#Miguel, I don't know the "MS Entity Framework" but the name makes it sound like a framework that is oriented towards editing data. 'Entity' is typically used for structuring a cache of database data in preparation for changing and updating that data back into the database. This does not seem like what you want to do.
Re-reading this question I believe that you have some sort of pivot generator you are using to create the view on-the-fly for the user. For this reason you do not intend to revise the Entity Model. I don't think you need an entity model at all.
An Entity Framework is likely to be looking for NOT NULL columns in order to find a 'primary key' or other row-level identifier that it can use. Why does it want these?
provide a key usable to update any row
provide key for paginating the result set
provide a key to support in-memory filtering of the result set
support dynamic sorting operations on the result set
I also surmise you have some sort of UI control that presents 'Entity' collections very nicely and so you want to use that control.
The control may not need an 'Entity' - check to see what its interface is. Perhaps there is a superclass of Entity or an interface that you can generate rather than an updateable Entity. If you can do that, you should be able to present it in the spiffy UI control and not hit the wall with your NULLABLE columns.
One of possible solutions is generating a new table on the fly based on results of query and tuning constraints for this table after that.
I don't like this method for too many dynamic SQL :)
Another solution is a prebuilt materialized view.
Look here (Oracle docs) for "ON PREBUILT TABLE Clause".
You need to update your model in Visual Studio (VS). Because this doesn't know what type information is in every column. Then you have to specify in the query of pivot table the data type. For example, Use to_number for specify a explicit conversion. When you going to update the model in VS you must based in for example materialized view (with explicitly defined data types). Please create Materialized view with explicitly defined data types based in the pivot table (this have to contain not only nvl function else defined data types, string, number, etc ) and then Update your model.
Only Materialized view? No, it can be a table (but is troublesome). Can be It direct of the pivot table? Does not always work (as in your case). Important Is to have defined data types.
You could use code-first if you don't have to many of these views, Scott Gu has a good article "Code first with existing database" that shows how to do this.
This might entail having 2 ways to access the db, which may or may not work for you.

How can I denormalize my clr entity, but keep my db tables normalized?

I have these two related tables Client (ClientId, Name) and ClientDescription (ClientDescriptionId, (FK) ClientId, Description). That is to say each Client can have many associated descriptions. Now, when displaying the a list of ClientDescriptions, I also need to know what the Name of it's associated Client is.
Now you'll probably say that I allready have this information, since I can simply follow my navigation property back to the associated Client and use its Name. I can't do that because I'm autogenerating a grid in Ria services, and this just gives me a count for navigation properties, and I haven't found a way to flatten this down in my metadata file. Hence why I want a property.
The whole idea is that I want to be able to add a new field to my database, update my entity classes from the database and regenerate my domain service, and the new field should just pop up in my grid. I shouldn't have to update my xaml just because my database happen to have an extra field.
So, what I would like to do is add a ClientName field to the entity (clr object), but keep my database clean (no such denormalization in the db).
So, I generated my edmx, and added a new property named ClientName. Set it to StoreGeneratedPattern.Computed, and compiled. I then get a nasty little error
Error 3004: Problem in mapping fragments starting at line NN: No mapping specified for properties (etc..)
The solution apparently is to generate my database from my edmx. (Or that's what answers to questions about that error seems to yield.) But this generates an actual DB-field, which I don't want, so that answer doesn't apply to my case.
So my question is: How can I denormalize my clr entity, but keep my db tables normalized?
Edit: I guess this question can be generalized a bit. The issue would be the same if ClientDescription contained a few numeric fields that I wanted to do some calculations on, and I wanted the result available as a field and the algorithm should be in c# rather than in my database.
To answer your more generalized question:
Entities are generated by the Entity Framework with a partial keyword.
This means that the code of an entity can be split in multiple source files in the same namespace and assembly. One will contain the generated code from the Entity Framework, the other will contain custom properties and methods.
If for example, your entity has the database fields Price and Amount you could add a property in the partial class TotalPrice which would return Price * Amount.
Then the algorithm will be C# and your database won't know about the extra property.

Entity Framework Design - Multiple "Views" for the data

I have a design question related to Entity Framework entities.
I have created the following entity:
public class SomeEntity {
// full review details here
}
This entity has as an example 30 columns. When I need to create a new entity this works great. I have all of the required fields in order to insert into the database.
I have a few places in my app where I need to display some tabular data with some of the fields from SomeEntity, but I don't need all 30 columns, maybe only 2 or 3 columns.
Do I create an entirely new entity that has only the fields I need (which maps to the same table as SomeEntity, but only retrieves the column I want?)
Or does it make more sense to create a domain class (like PartialEntity) and write a query like this:
var partialObjects = from e in db.SomeEntities
select new PartialEntity { Column1 = e.Column1, Column2 = e.Column2 };
I am not sure what the appropriate way to do this type of thing. Is it a bad idea to have two entities that map to the same table/columns? I would never actually need the ability to create a PartialEntity and save it to the database, because it wouldn't have all of the fields that are required.
Your first approach is not possible. EF doesn't support multiple entities mapped to the same table (except some special cases like TPH inheritance or table splitting).
The second case is common scenario. You will create view model for your UI and either project your entity to view model directly in query (it will pass from DB only columns you project) or you will query whole entity and make conversion to view model in your application code (for example by AutoMapper as #Fernando mentioned).
If you are using EDMX file for mapping (I guess you don't because you mentioned ef-code-first) you can use third approach which takes part from both mentioned approaches. That approach defines QueryView - it is EF based view on the mapped entity which behaves as a new read only entity. Generally it is reusable projection stored directly in mapping.
What you proposed as a first solution is the "View model paradigm", where you create a class for the sole purpose of being the model of a view to retrieve data and then map it to the model class. You can use AutoMapper to map the values. Here's an article on how to apply this.
You could create a generic property filter method that takes in an object instance, and you pass in a string array of column names, and this method would return a dynamic object with only the columns you want.
I think it would add unnecessary complexity to your model to add a second entity based on the same data structure. I honestly don't see the problem in having a single entity for updating\editing\viewing. If you insist on separating the access to SomeEntity, you could have a database view: i.e. SomeEntityView, and create a separate entity based on that.

Where does the 'Name' property in a DBML come from?

I'm using Linq-To-Sql and inside my DBML there are objects built from the database connection provided.
If you click on an association line between two tables and view the properties on it, you will get the following:
Cardinality
Child Property
Access
Inheritance Modifier
Name
Parent Property
Access
Inheritance Modifier
Name
Participating Properties
Unique
My question is, where does Linq-To-Sql get the "Name" properties from? Where is the correlation to the actual database?
I ask this because if this table happens to be a parent to several children, Linq-To-Sql will just simply name these properties, "SomeParentName", "SomeParentName2", "SomeParentName3" , etc. So you'd have to go into the DBML and manually change these names to something meaningful every time you update this table.
Any help you can provide would be appreciated.
Part 2 of my question might be how do you guys handle these situations?
As for the Name: It takes the child / parent and comes up with something based on some internal voodoo. Don't ask me how.
As for Part 2: If you tend to have to redo stuff every time you update something I STRONGLY suggest switching to Entity Framework. It's very similar, but you can just hit "update" and your modifications are kept.

Categories