Map a property in the entity framework to a different type - entity-framework

I have a SQL Server 2008 database. I have a bunch of fields in TableA that are just strings that corresponds to booleans. So every value is either true or false. The edmx I generated using Entity Framework 4.0 has them as strings. This is technically correct but I would like to have them mapped as Booleans instead. Is this possible? If so how can I accomplish this?
Thanks much!

You could create a partial class alongside the generated one and add the bool property there with code to go back and forth from bool to string version. You could also mark the generated property as protected or internal to hide it from the rest of your code.
It's not ideal since the bool property cannot appear in query expressions unless you first force the query to happen using, for example, .ToList().
Your best bet would be to fix the database.

Related

value from database computed property is Null in codefluent entity property

My MS SQL 2014 database table has a computed property column which uses a database function. Using SQL Server Management Studio, a query against the table lists the computed property values as expected.
The Codefluent model created via the import wizard shows the Entity with the computed column as a property. The underlying .cpf file defines the property with "d3p1:compute=" and the list of parameters that are used by the database function.
When an entity or the collection of entities is loaded, the properties which are used in the computed property have values, yet the computed property has a value of nothing/null.
How do I get Codefluent to read the computed value from the database table and have the value included in the entity's properties?
This is a bit tricky. First of all, you should declare the property like any other property. Then you must instruct the SQL producer to declare a formula on that column. You can do that with a custom 'compute' attribute in the SQL producer namespace. You can set it with the Visual Studio modeler like this:
In this example I've created an int property that is just another column value multiplied by 2.
Optionally, you can declare the property to be 'read on save' because most of the time, you want to read the computed value after a save, not only on load operations:
Once this is all done, this sample console app should display 30:
class Program
{
static void Main(string[] args)
{
var c = new Customer();
c.Name = "killroy";
c.Age = 15;
c.Save();
Console.WriteLine(c.Age2); // will display 30
}
}
If Simon Mouriers solution solves your problem than that is probably the best approach. However, there are 2 other options
RAW View Method
After you create a Codefluent Entities View click on the Edit Where button and it will allow you to create a RAW View
You can than specify the advanced property "UsedForMethods".
WARNING: Related entities will use the table instead of the view. This is by design and there is an article somewhere on the knowledge center on how to get around it. http://www.softfluent.com/product/codefluent-entities/knowledge-center/
Rename SQL Tables and Create a SQL View with the Same Name as the Original Table - This method is a hack, Softfluent discourages this approach, I love it because I know exactly what is happening under the scenes. I have used it with success in a scenario in which I needed soft deletes. I have automated the process with 2 stored procedures that handle the renaming. Using this approach requires running one of the stored procedures to undo the name changing prior to building the model. The other stored procedure handles the renaming after building the model. I'll post the stored procedures and how I use them within a couple of days.

entity framework "composite" property?

I am using EF 4.1, code first and want a property on a customer entity built up of a constant string value and the customerId zero padded to act as a customer reference.
I might be being a bit daft but am struggling to work out how I can achieve this without
A) having to savechanges twice, once to get the Id then set my reference and save again
B) having a partial Customer class that simply provides a getter returning constant + CustomerId.Tostring("000000")
Is this "doable" with code first?
If you can change the database I would make a computed column for this. Thus, you leave it to the database to generate a reference value and it will also be available to other consumers of the database (if any).
Your Customer class will have a property like CustomerReference (string) that maps to the computed column and that is configured to have DatabaseGeneratedOption.Computed which will cause EF to read the value after inserting an object.

LINQ to Entities (.NET 4.0)

I have the code below (this is actually part of a much more complicated query, but I have isolated the issue to this particular line to help with debugging) which per everything I have read should create an IN clause in SQL, assuming I am using EF4. As far as I can tell, I am using EF4 (We are using .NET Framework 4 for our projects and when I look at the System.Data and System.Data.Entity they both say version 4.0.0.0 for all the projects)
int[] assessmentIDs; // this is just here to show what this is,
// but it is a params parameter passed to this methed
var assessments = from cert in container.ProctorAssessmentCertifications
where assessmentIDs.Contains(cert.AssessmentID)
select cert.ID;
However, when I run this, I get the runtime error:
LINQ to Entities does not recognize the method 'Boolean Contains[Int32](Int32[], Int32)' method, and this method cannot be translated into a store expression.
When I use LinqPad, it does correctly output an IN clause like one would expect in EF4.
My questions are:
A. What am I doing wrong and how do I make this work?
B. How do I force EF4 to be called if in fact it's not? I can find no reference in any web.config file that point it to the older version.
Contains does not get translated into valid SQL because assessmentIDs is not IQueryable, it is an in-memory object. So you'll have to pull the data out first, and then do the check.
var assessments = (from cert in container.ProctorAssessmentCertifications
select cert.ID).ToList() //no longer IQueryable.
var result = assessments.Intersect(assessmentIDs);

Is there a way to map a Date column to a string property in EF?

I know I can solve this by adding another property to my entity which will contain the conversion between types but was wondering if it is possible with EF CF.
Do you need this for UI presentation (of the DateTime value) reasons?
If so, you might want to consider defining a separate View model class, and using something like AutoMapper to map the properties between the two.

GUID or int entity key with SQL Compact/EF4?

This is a follow-up to an earlier question I posted on EF4 entity keys with SQL Compact. SQL Compact doesn't allow server-generated identity keys, so I am left with creating my own keys as objects are added to the ObjectContext. My first choice would be an integer key, and the previous answer linked to a blog post that shows an extension method that uses the Max operator with a selector expression to find the next available key:
public static TResult NextId<TSource, TResult>(this ObjectSet<TSource> table, Expression<Func<TSource, TResult>> selector)
where TSource : class
{
TResult lastId = table.Any() ? table.Max(selector) : default(TResult);
if (lastId is int)
{
lastId = (TResult)(object)(((int)(object)lastId) + 1);
}
return lastId;
}
Here's my take on the extension method: It will work fine if the ObjectContext that I am working with has an unfiltered entity set. In that case, the ObjectContext will contain all rows from the data table, and I will get an accurate result. But if the entity set is the result of a query filter, the method will return the last entity key in the filtered entity set, which will not necessarily be the last key in the data table. So I think the extension method won't really work.
At this point, the obvious solution seems to be to simply use a GUID as the entity key. That way, I only need to call Guid.NewGuid() method to set the ID property before I add a new entity to my ObjectContext.
Here is my question: Is there a simple way of getting the last primary key in the data store from EF4 (without having to create a second ObjectContext for that purpose)? Any other reason not to take the easy way out and simply use a GUID? Thanks for your help.
I ended up going with a GUID.
The size/performance issues aren't
critical (or even noticeable) with SQL Compact, since
it is a local, single-user system.
It's not like the app will be
managing an airline reservation
system.
And at least at this point, there
seems to be no way around the "no
server-generated keys" limitation of
the SQL Compact/EF4 stack. If someone has a clever hack, I'm still open to it.
That doesn't mean I would take the same approach in SQL Server or SQL Express. I still have a definite preference for integer keys, and SQL Compact's bigger siblings allow them in conjunction with EF4.
Use a Guid. AutoIncrement is not supported on Compact Framework with Entity Framework.
Also, if you ever want to create a application which uses multiple data sources, int PK's are going to fall apart on you very, very quickly.
With Guid's, you can juse call Guid.NewGuid() to get a new key.
With int's, you have to hit the database to get a valid key.
If you store data in multiple databases, int PK's will cause conflicts.
What I've done for SQL CE before, and I assume we have a single application accessing the database, is to calculate the MAX value on startup and put it in a static variable. You can now hand out sequential values easily and you can make the code to generate them thread safe very easily.
One reason to avoid Guids would be size = memory and storage space consumption.
You could also query SQL Compact metadata like so:
SELECT AUTOINC_NEXT FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Categories' AND AUTOINC_NEXT IS NOT NULL