It would be really handy to be able to somehow say that certain properties in the generated entity classes should, for example, be decorated by (say) validation attributes (as well as Linq To SQL column attributes).
Is it a T4 template someplace? Or are there other ways to skin the cat?
Damien Guard has written T4 templates that can be customized. See:
http://damieng.com/blog/2008/09/14/linq-to-sql-template-for-visual-studio-2008
...and:
http://visualstudiomagazine.com/listings/list.aspx?id=560
No, the SqlMetal tool is what handles the generation of the C# and it is defined within itself how the C# is generated (or VB for that matter).
I'm not familiar with the template style you want but you could try exteding the generated classes (if they aren't that big a change) since they are just partial classes.
Otherwise you would need to write/ look for a custom implementation of SqlMetal
Unfortunately, with partial classes you cannot add attributes to a member from another part of the partial class - i.e. if SqlMetal defines property Foo, you can't add an attribute to Foo in your own half of the .cs.
This takes away one of (usually) the more powerful ways of customizing such files... you would probably have to either take a chance and hand-edit the generated file (after detaching it from the dbml completely) - or write your own dbml parser frmo scratch (mayhbe using xslt). Not easy.
The workaround in Dynamic Data is by using a metadata class which can be decorated:
[MetadataType(typeof(Product_Meta))]
public partial class Product
{
public partial class Product_Meta
{
[Range(5, 50, ErrorMessage = "The product's reorder level must be greater than 5 and less than 50")]
public object ReorderLevel { get; set; }
}
}
http://rachelappel.com/asp-net-dynamic-data/custom-validation-in-asp-net-dynamic-data-using-attributes/
Related
I'm using entity framework. It auto generated an Answer class. But I cannot modify this class as it will be overwritten if code is regenerated.
Is there a way/technique to add data annotations using this class?
The reason I ask is that I have a Create Answer view that uses the Answer class. Hence, I want to add data annotations such as Required, etc.
If I cannot add data annotations to the Answer class, then I have to create an "AnswerDuplicate" class, pass that into the view, and also use that in my Create() method. However, I then have to map all the values from AnswerDuplicate to an instance of Answer, since Answer is what I "add" to the entity.
Seems like extra work since Answer is autocreated (class and the binding in Create() method). Would be nice if I can just add data annotations.
If this is not possible, then is my only option to create an "AnswerDuplicate" class and use that in place of the Answer class?
My suggestion is: Use ViewModels.
I always consider creating a ViewModel when editing/viewing data - rather than passing the model object directly down to the view.
How Will This Help?
The logic to display it in the view (with Required, DataType and validation such like) can be left down to the ViewModel; while your Model is just left as a normal all-intents-and-purposes class (in your case, a generated one).
As an example, you could have an AnswerViewModel, which contains all of your display/validation logic, to then use in your corresponding View.
How Do I Save Time Mapping Properties?
You can use AutoMapper (or other similar auto-mapping packages) to then automatically map the properties between your model and the view model, for easy updating of entities etc.
This then saves you time having to write lines-upon-lines of code to update entities - which may essentially need to change over time - this can be a big problem (and a huge PITA) if refactoring/adding extra properties across different classes.
How Does This Help Going Forward?
Well, because you are not leaving the logic up to your class:
Let's say you have 3 different views for different purposes (Add, Edit, Delete)
If (for some reason) you need to show/display something differently in only one particular view, you are able to just apply/change the logic in the relevant ViewModel; rather than worrying about updating the Model and having breaking changes affect everything else.
Here is a handy tutorial on How To Use ViewModels In MVC: http://rachelappel.com/use-viewmodels-to-manage-data-amp-organize-code-in-asp-net-mvc-applications/
I do hope this helps, somewhat :)
If you need me to provide any examples - just let me know.
I think the best solution is to use ViewModels as #Geoff James said, but if you don't like to add different classed you can write a partial class and add the MetadataType attribute to it and the add the attributes you want like Required to its properties.
public partial class Answer // this is auto-generated
{
public long AnswerID {set; get;}
}
[MetadataType(typeof(Answer ))]
public partial class Answer // this is what you can write
{
[Required]
public long AnswerID {set; get;}
}
remember that both class must have a same namespace.
And other solution to your problem is the you can switch to Code First
I've generated a code base for service communication from a WSDL file which resulted in around 100 classes containing the following:
public class SomeClass {
private string _someVar;
public string SomeVar {
get { return _someVar; }
set { _someVar = value; }
}
}
Is it possible to automagically turn everyone of them into auto properties? Maybe using ReSharper or some regex magic?
If you just need to do this once, you can let R# do it for you with a Code Cleanup action.
Right-click on the project (or solution, or single source file), select "Cleanup code..." and then use profile which includes "Use auto-property, if possible." (If you don't have such a profile already, you can edit your profiles from that dialog.)
However, I would strongly advise you to separate generated code from hand-written code. Make all your generated code use partial types (and potentially partial methods) - that way you can create a hand-written partial type which merges with the auto-generated code, without being in the same file. You don't need to look at the generated code, and you can replace it with another version later without worrying about any custom changes.
The following Visual Studio regex will find the pattern you have above when plugged into the "Find & Replace" tool.
private:Wh*:i:Wh*:i;:Wh*public:Wh*(:i):Wh*(:i):Wh*\{:Wh*get:Wh*\{[^\}]*\}:Wh*set:Wh*\{[^\}]*\}:Wh*\}
And this pattern will do the replace.
public \1 \2 { get; set; }
In C#, I started using attributes to define my class. I'm writing a plugin system in which classes require some metadata to be recognized as plugins.
I don't know exactly anymore how the Visual Studio Extensions did it, but I require an opinion or design rule which tells me if I should create an attribute with many (optional) parameters or use more attributes with less parameters.
For example, the decision is about these two different code pieces:
Single attribute, many properties:
[Plugin("Image Tools", Author = "PacMani", Description = "blahblah",
Website = "http://blahblah.contoso.com/", Image = "Icon32x32.png")]
public class ImagePlugin : Plugin
{
// ...
}
versus
[Plugin("Image Tools", Author = "PacMani", Description = "blahblah")]
[Website("http://blahblah.contoso.com/")]
[Image("Icon32x32.png")]
public class ImagePlugin : Plugin
{
// ...
}
or even a version which splits up "Author" and "Description" into single attributes.
My idea was to not split thematically grouped attributes. But where do such groups start and end? The above properties are all of the group "Details" or "Descriptive information" about the plugin.
In your case I would recommend to put all these informative pieces of data as one attribute. Why? Because :
They are all connected with one concept - plugin
They are only informative
It would probably be different if there would be some logic connected with each of the property- then would consider splitting them.
There is one other scenario you might be willing to split these into separate attributes - in case you can logically separate the types of plugins. So then you could have a base PluginAttribute with only basic properties, then e.g. ImagePluginAttribute attribute which inherits from PluginAttribute and has some additional properties, etc.
But I would not divide it into separate attributes by properties (WebsiteAttribute, AuthorAttribute, VersionAttribute) in your case.
Might of misunderstood the problem ,but why not use a config file? seems more appropriate then attributes in this case no?
You can recognize the classes as plugins by their inheritance, and the rest of the metadata in those attributes seems like just meta data that should be defined as either properties in the class or config for easy access (if they change outside of the code - stuff like website).
How would you design an application (classes, interfaces in class library) in .NET when we have a fixed database design on our side and we need to support imports of data from third party data sources, which will most likely be in XML?
For instance, let us say we have a Products table in our DB which has columns
Id
Title
Description
TaxLevel
Price
and on the other side we have for instance Products:
ProductId
ProdTitle
Text
BasicPrice
Quantity.
Currently I do it like this:
Have the third party XML convert to classes and XSD's and then deserialize its contents into strong typed objects (what we get as a result of this process is classes like ThirdPartyProduct, ThirdPartyClassification, etc.).
Then I have methods like this:
InsertProduct(ThirdPartyProduct newproduct)
I do not use interfaces at the moment but I would like to. What I would like is implement something like
public class Contoso_ProductSynchronization : ProductSynchronization
{
public void InsertProduct(ContosoProduct p)
{
Product product = new Product(); // this is our Entity class
// do the assignments from p to product here
using(SyncEntities db = new SyncEntities())
{
// ....
db.AddToProducts(product);
}
}
// the problem is Product and ContosoProduct have no arhitectural connection right now
// so I cannot do this
public void InsertProduct(ContosoProduct p)
{
Product product = (Product)p;
using(SyncEntities db = new SyncEntities())
{
// ....
db.AddToProducts(product);
}
}
}
where ProductSynchronization will be an interface or abstract class. There will most likely be many implementations of ProductSynchronization. I cannot hardcode the types - classes like ContosoProduct, NorthwindProduct might be created from the third party XML's (so preferably I would continue to use deserialization).
Hopefully someone will understand what I'm trying to explain here. Just imagine you are the seller and you have numerous providers and each one uses their own proprietary XML format. I don't mind the development, which will of course be needed everytime new format appears, because it will only require 10-20 methods to be implemented, I just want the architecture to be open and support that.
In your replies, please focus on design and not so much on data access technologies because most are pretty straightforward to use (if you need to know, EF will be used for interacting with our database).
[EDIT: Design note]
Ok, from a design perspective I would do xslt on the incoming xml to transform it to a unified format. Also very easy to verify the result xml towards a schema.
Using xslt I would stay away from any interface or abstract class, and just have one class implementation in my code, the internal class. It would keep the code base clean, and the xslt's themselves should be pretty short if the data is as simple as you state.
Documenting the transformations can easily be done wherever you have your project documentation.
If you decide you absolutely want to have one class per xml (or if you perhaps got a .net dll instead of xml from one customer), then I would make the proxy class inherit an interface or abstract class (based off your internal class, and implement the mappings per property as needed in the proxy classes. This way you can cast any class to your base/internal class.
But seems to me doing the conversion/mapping in code will make the code design a bit more messy.
[Original Answer]
If I understand you correctly you want to map a ThirdPartyProduct class over to your own internal class.
Initially I am thinking class mapping. Use something like Automapper and configure up the mappings as you create your xml deserializing proxy's. If you make your deserialization end up with the same property names as your internal class, then there's less config to do for the mapper. Convention over Configuration.
I'd like to hear anyones thoughts on going this route.
Another approach would be to add a .ToInternalProduct( ThirdPartyClass ) in a Converter class. And keep adding more as you add more external classes.
The third approach is for XSLT guys. If you love XSLT you could transform the xml into something which can be deserialized into your internal product class.
Which one of these three I'd choose would depend on the skills of the programmer, and who will maintain adding new external classes. The XSLT approach would require no recompiling or compiling of code as new formats arrived. That might be an advantage.
Is there an automatic way to add base classes to Linq2Sql entities?
I know I can define a partial and implement that but there has to be an automated way, right?
The LINQ-to-SQL code-generator supports this directly.
The base-class for the data-context can be set in the designer, as the Base Class property. Alternatively, edit the dbml directly: right click, "Edit With...", "XML Editor"
To change the base class for the entities, set the type:
<Database EntityBase="Some.NameSpace.Foo" ... >
To change the base class for the data-context, set the type:
<Database BaseType="Some.NameSpace.Bar" ... >
In both cases, use the fully-qualified type in the attribute. Et voila.
Note that because it is very literal, you can also use this approach to make your entities implement an interface - for example, when my classes have properties like LastUpdated and UpdatedBy, I might have an IAuditable interface that defines these. Then I can put code in my data-context's SubmitChanges (override) that calls GetChangeSet() and sets these values for all the IAuditable entities being updated; very sweet.
EDIT: Marc's answer is clearly the right way to go in this case, but I'm leaving this answer here for posterity - it's a handy trick to know about in some cases, where you only need a partial class to change the inheritance/interfaces of a class.
I don't know of any automated way, but if you wanted to do this for multiple classes and only wanted to specify the base class, you might consider creating a file just for the partial class declarations. I use this approach in Protocol Buffers to make the internal representation classes which are autogenerated implement a particular interface.
See PartialClasses.cs for this example as code. (Ignore the TODO - it's fixed locally, but I haven't pushed for a little while :)
Some people have written their own code templates in place of the DBML approach. Going that route you can easily add the base classes yourself.
LINQ to SQL template for Visual Studio 2008 is a good starting point