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
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 got a class called List_Field that, as the name suggests, builds list input fields. These list input fields allow users to select a single item per list.
I want to be able to build list input fields that would allow users to select multiple items per list, so I have the following dilemma:
Should I do that through implementing a multiple_choice_allowed property into the existing List_Field property, or should I implement a Multiple_Choice_List_Field subclass of the List_Field class?
What's the engineering principle that I should follow when confronted with dilemmas like this one?
Take a look at the SOLID principles. They'll help you in your designs. In particular, the single responsibility principle will tell you not to mix the two concerns in one class, and the Liskov substitution principle will tell you not to create subclasses that break the contract of superclasses, like what you're also proposing.
So what would be the solution in your case? You could create an abstract base class that would be agnostic to the type of selection and then create 2 subclasses, one for single selection and another for multiple selection.
Depends on presence/lack of object evolution - if you want special case, sub-classing or injecting (DI) "select" behaviour (strategy) is good.
But if you also want to allow Field_List to change its behaviour dynamically, then property or mutating method is the only way to go.
Example: Sign-up screen with different "plans" - basic, where you can only select one thing and premium, where you can select as much as you want. Change of plan will switch between drop-down and multiple checkboxes, while still having the very same object including its contents.
I would vote for property/mutate method.
Personally I would go for the Multiple_Choice_List_Field way. I don't think there is a strict standard or an engineering principle that would make you to do it one way instead of another.
The more important thing here is to choose one way to do it and follow it whenever you encounter such a dilemma. You should be consistent, but which way you go is your own choice.
I would choose the subclass because this way you won't have to bloat your List_Field class with additional checks and requirements. Of course there are other considerations such as if you need to switch the multiple choice and single choice at runtime it would be better to go for the boolean property (although subclass will work too, but doesn't feel natural to me).
The other thing is for List_Field you might need more than a single property to handle multiple choices, depending on your current implementation. For example a new property to return an array of the selected items.
Just do it the way it's most comfortable for you to build and maintain (and eventually extend).
Should I do that through implementing
a multiple_choice_allowed property
into the existing List_Field property
If you can do that, I think it's the best solution because this way you avoid class proliferation.
If in doing that you are complicating too much your List_Field class, maybe create a derived class can have some benefits regarding the maintainability of your code.
Personally, I would say neither: instead use a constructor that takes multiple_choice_allowed, and then have a property exposing ListFields as a collection (with just one element when only one is allowed, all of them when more than one is allowed). Make it readonly (which means that you should copy it whenever you return the list).
i am using LINQ to SQL, 3.5 Framework and i would like to know which is the best way to design the classes. Taking a very simple example of User table.
If i have a User table with 3 different roles of Customer, Admin, Cashier.
I would say i will need to create 3 classes for each of the role. e.g. customers.cs...
Question:
1) Since Linq .dbml already has the User auto generated from my user table, all the properties are already predefined, do i still need to create a User.cs class to be inherited by 3 of the classes role above? This is because i cannot add any duplicate properties in the User.cs e.g. Public string Name {get;set;} would failed because in the .dbml already has the property call Name.
2) This question will be very basic question i think... but i find it useful if i can know the correct answer. How should i park my functionality into the correct class? e.g. PrintYearlyReport(), CheckStaffSalary(), ModifySale(), UpdateGovernmentTax().... all of these functions are under the role of Admin. It will be very readable if we have admin.PrintYearlyReport(), admin.ModifySale()... However, if we park all the admin's functionalities in the Admin.cs file, then this file would be very very huge!!! For OOP sake, we need to have classes like e.g. Sale.cs, Payment.cs, Invoice.cs. If we split all those functionalities into each different classes, then we will no longer have the elegant way of calling the admin.PrintYearlyReport() anymore..
You can create sub-classes of the User class, i.e., Customer, Admin, and Cashier, then specify the correct class based on the user's role. Sometimes we design by creating a method like User.IsInRole or User.HasAccessTo methods that you can call to verify they can access or use certain functionality.
You can split the functionality into separate files but still have them in the same class by using partial classes. If you define public partial class Admin you can define the class Admin in as many separate files as you want, and all of the properties will be added together when building the project.
Let’s keep it simple. Usually the best answer is the simplest one. Do you need to have more than one class? May be may be not. If the differences between the roles is simple one liners, than why the need to create subclasses? I usually start out with one class and as the behavior is better defined and you can clearly diferentiate the subclasses than you create them. With that said you should think about what you want your objects to look like, and by that I mean what dependencies you what to create and what functionality will be shared. Composition vs inheretance When I think of users and roles I think: user has role x, not user is role x because roles can change. Common functionality and properties should be in a base class. May be you can put your access rules in a class that lives within the user:
User{
Name
Role
Rules{ }
}
So you can say
if(user123.Rules.CanPrint())
{
Print();
}
Create the rules inside the user and pass in the role(s) so the rules class can figure out what this user can do. This is how I would do it. My point is, don't get hungup on what class should go where. Define objects and behavior and let the classes define them selves. You will learn to spot when a class is getting too big and need to breake it up.
You can add stereotype to your class diagram and get live persistence annotations in your java code. If you use Hibernate then from your code you can get your database. No need to create an object UML model and another model for your database.
This is what I do and really cool !!
It only works with Java and not with c#.
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.
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/