EF T4 Template - Conditionally emitting custom attributes - asp.net-mvc-3

I'm using EF 4.1 "database first" on a project. Using the T4 template, I am conditionally decorating my generated properties with attributes for things like Required, DisplayName, MaxLength. In my T4 template, inside the WriteProperty method, I have something like:
var maxLength = edmProperty.TypeUsage.Facets.Where(f => f.Name == "MaxLength").FirstOrDefault();
if (maxLength != null && maxLength.Value.ToString() != "Max")
{#>
[MaxLength(<#= maxLength.Value #>, ErrorMessage = "<#=edmProperty.Documentation != null ? edmProperty.Documentation.LongDescription : edmProperty.Name #> cannot exceed <#=maxLength.Value #> characters.")]
<#+}
This works great for information that can be inferred from the edmx, but there are some things that are custom and simply not available.
As an example, suppose I want to decorate an EmailAddress property with a custom regular expression-type attribute. How can I "single out" email address fields in my model automatically and apply this attribute without checking the property's name?
Are there ways to "extend" EdmProperty perhaps and add custom properties such as IsEmailAddress?
Thanks!

I think you (kind of) can do that. I have not tried this but I believe if you add an attribute in your namespace to the Edmx file you will be able to access it through metadata properties. Something like this:
<Property Name="ID" Type="Int32" Nullable="false" myNs:regex="xxx" xmlns:myNs="http://tempuri.org" />
Then you could read the value like this (given you have the EdmProperty):
var metadata = edmProperty.MetadataProperties.Single(p => p.Name == "http://tempuri.org:regex");
Console.WriteLine(metadata.Value);
The only problem here is that whenever you update the model from the database the edmx file may be overwritten and you may lose whatever annotations you put in your edmx file.

No, there is nothing. EF model designer still has nothing for extending the model with custom metadata, even for validation. You could try naming conventions of course or reinvent the wheel and add your own metadata file aside, but easier way for now is just write validation attributes and metadata types manually for partial classes.
I would definitely vote for adding this feature in EF.

Related

Dynamic property key

My project has several events and I store event IDs in Site Properties and as each event page extends the same core template I want to assign the specific event ID to a generic variable.
The issue is that when I try to insert a variable inside the property key reference freemarker returns syntax errors. Is there any way around this?
${sectionName}
//rootSection
<#property key="eventID-rootsection" />
//32465
<#assign eventID = <#property key="eventID-${sectionName}" /> >
//syntax error
The problem is that property is defined as a directive (maybe as a macro), and not as a method (or function). You need a method (or function) version of it. Then your example would look like:
${sectionName}
//rootSection
${property("eventID-rootsection")}
//32465
<#assign eventID = property("eventID-${sectionName}")>
To define property as such, either implement TemplateMethodModelEx or use the #function directive.

Is there a way to add a filter to the Entity Framework layer to exclude "IsArchived" records?

I have records marked up as "IsArchived". I am looking for an expedient way to exclude these records from a current MVC3 / EF3 web application.
Is there a way to add some kind of "IsArchived" filter to the EF layer. In my case I have a seperate Model project with tables/views represented as POCO entities, and the mappings contained in the CSDL and SSDL files.
Huge thanks for any assistance.
EDIT:
I am using "ObjectContext" and not "DbContext", mainly due to the Data Modelling tool that I am using. This tool creates the context and POCO files.
I am wondering whether I can edit this context file like the following:
public ObjectSet<StdOrg> StdOrg
{
get
{
if ((_StdOrg == null))
{
_StdOrg = base.CreateObjectSet<StdOrg>("StdOrg");
// new line below. Got cast error tween both sides.
_StdOrg = (ObjectSet<StdOrg>) _StdOrg.Where(r => r.IsArchived == false);
}
return _StdOrg;
}
}
Take a look at this http://www.matthidinger.com/archive/2012/01/25/a-smarter-infrastructure-automatically-filtering-an-ef-4-1-dbset.aspx
Basically a filtering DBSet implementation that the example basically shows being used for Soft Delete. We use it without issue in our App.
However we are using DBcontext so not sure how this would work with Object Context or how it could be adapted

breeze: custom enum values

Enums come back from the server as myEnum.SomeValue but what I'd like to show on screen is a formatted value such as "some value" instead of SomeValue.
That could be part of an attribute on the server-side model but it won't be passed in the metadata.
What's the best place then to do that kind of thing with breeze ?
We've discussed the idea of "extensible" metadata for Breeze but have not yet implemented it. Please vote for this here.
But in the meantime, there is nothing stopping you from "enhancing" the metadata returned by Breeze yourself. The best way to do this would be to add your own properties to either the "MetadataStore", "EntityType" or "DataProperty" classes.
The advantage of adding your custom metadata to existing metadata objects is that this data will be available whenever you work with any of the basic Breeze metadata.
Perhaps something like this: ( I haven't actually confirmed that this code is correct)
var custType = myEntityManager.metadataStore.getEntityType("Customer");
// assume that the 'status' property is actually an enumerated value where you want to
// add some custom metadata.
var statusProp = custType.getProperty("status");
// enumDescriptions is your custom property
statusProp.enumDescriptions = {
"PaidUp": "Paid Up",
"Delinq": "Delinquent",
"InArr": "In Arrears"
};
Now anywhere that you get given the "status" dataProperty, ( such as in a Validation), you will also have access to your "enumDescriptions"
Hope this makes sense.

How to specify composite action variables in magento dataflow xml profiles

I have created some custom actions to use inside a Magento Dataflow profile. I would like to pass in composite parameter values (arrays or dictionaries) to the action, similar to the map var you can pass to the default parser actions. I.e., I would like to do something like this:
<var name="attribute_map">
<map name="sColore"><![CDATA[colore]]></map>
<map name="sMarca"><![CDATA[marca]]></map>
<map name="sFornitore"><![CDATA[fornitore]]></map>
</var>
The variable turns out as null in this case, although, upon fiddling with the xml and skimming through the code, it seems that this pattern only works with <var name="map">. Puzzling and disappointing. I also have not been able to find even the slightest hint about the relevant xml schema in any documentation whatsoever...
Any idea on this? Thanks!
(I am working with Community Edition version 1.7.0.2)
If i understand right what you ask, you could overwrite the system/convert/profile/wizard.phtml from admin and add another section similar to existing map but the form elements should have name="gui_data[attribute_map]...[]".
Then you should overwrite the _parseGuiData method from Mage_Dataflow_Model_Profile to form the correct profile actions xml.
Hope that helps.
You can't, using the core implementation.
The var elements can only contain simple text, unless the element has the attribute name="map", in which case the profile parser will search for children map elements and use them to populate a php associative array.
The relevant code is inside the importProfileXml method of the Mage_Dataflow_Model_Convert_Profile_Collection class:
if ($varNode['name'] == 'map') {
$mapData = array();
foreach ($varNode->map as $mapNode) {
$mapData[(string)$mapNode['name']] = (string)$mapNode;
}
$container->setVar((string)$varNode['name'], $mapData);
}
To extend this behavior you should override this class with a custom (sub)class through the usual magento class override methods.

Allow non filled fields

I have a model for an ASP.NET MVC view containing several properties:
Subject
Message
Id
While subject and message are required, Id isn't required (it's hidden and only set
for an existing entry). Unfortunately, MVC validates it as required ( The If field
is required) even though I haven't set the Required attribute.
Has someone a solution? Haven't found a solution here, maybe just searching wrong...
Kind regards,
Sascha
If Id is an Int... you can try making it Int? (nullable Int).
If it is nullabe, I think MVC will not validate it.
Another way, would be place a default value in that hidden, lets say a "-1"... and on the controller you can check it.
By default, ASP.Net Mvc will treat non-nullable properties as 'required' - even if you do not add the [Required] attrtibute to the property. If your id is of type int - it is not-nullable and therefore required.
You have basically two options:
Change your Id property to int? - ie a nullable int.
Change the default setting for MVC to not regard non-nullable attributes as required.
Option 1 is straight-forward. For option 2 add the following to the Application_Start method in your global.asax
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = true;

Resources