D365FO x++ syscomputedcolumn table name - axapta

How can you use the syscomputedcolumn class to retrieve a table or field name for an entity? this is fairly easy using virtual field entity postload method something like
public class SysDatabaseLogHeaderEntity extends common
{
public void postLoad()
{
super();
this.TableName = tableId2Name(this.table);
}
}
but there's a rumour that virtual fields won't be supported in upcoming synapse link for D 365 FnO so want to know how to do this with computed columns...
https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/data-entities/data-entity-computed-columns-virtual-fields

SysComputedColumn is used to help create computed columns in views.
Supposing for some reason you want a column in which every row contains the string value "CustTable", you'd create create a method (AX 2012 syntax):
public static server string TableNameColumn()
{
return SysComputedColumn::returnLiteral(tableStr(CustTable));
}
and then you'd add a computed column to the view as outlined here: https://learn.microsoft.com/en-us/dynamicsax-2012/developer/walkthrough-add-a-computed-column-to-a-view
Note: hopefully this is a toy example, there is no reason to ever actually do this particular column. Or really any fully static columns.
View computed columns are essentially based on static server methods which return the SQL definition for the computed column, and then the SysComputedColumn class has a bunch of helper methods to let you build those SQL string statements without using specific implementation knowledge of the backend database such as column names.
A complete description is beyond the scope of this comment, but the big one you'll use is SysComputedColumn::returnField(view,datasource,field) which gets the specified field from the specified datasource in the specified view. You want to use intrinsic functions for these parameters to keep your cross references valid (https://learn.microsoft.com/en-us/dynamicsax-2012/developer/intrinsic-functions).
There will be a lot you can't do though. These are sql only so they cannot send individual rows into X++ business logic. You need to reconstruct said business logic in SQL which can't always be done easily.
I like to keep those methods public so I can info them out and test them in SQL directly. I'm guessing you can't access the sql in d365, but looking at the string returned from your method can still help in troubleshooting.

Related

ExpressMapper tutorial assumptions -- I don’t know where to start

Current project:
ASP.NET 4.5.2
MVC 5
EF 6
In all honesty, I have never made use of a mapper before, and while the ExpressMapper tutorial bounces across the high-altitude highlights, it makes several assumptions about knowledge that I don’t have.
So in no general order:
The product is supposed to have all its code centralized in one spot. Where is this spot? Where do I put it? The examples start out with,
public void MappingRegistration() {
Mapper.Register<Product,ProductViewModel>();
}
But I don’t know where to put this. Does it go into its own file or is it in another file, such as within App_Start?
If it is elsewhere in the project, do I create it under its own namespace?
If I have a viewModel that is filled in a different way than its dataModel is filled, how do I handle each type separately? As in, the data is pulled out of the DB and fills the viewModel with completely different conditional rules than how the data is pulled from the viewModel and inserted into or updated back to the database.
How do I bring in external conditionals that affect how the data and which data is inserted into the DB, such as the Role of the user, their UserId and UserName, and various project Settings? Depending on conditionals, some entries may end up with a null value instead of an actual value. How can I do business logic validation using these conditionals (User is actually updating his own record, by comparing their session UserId with the UserId stored in the DB)?
Right now I am doing a lot of manual mapping in the Models but this is problematic especially since the method I am using (to cut down on code in the controller) means that during an update I cannot examine an entry in the DB prior to updating it in the DB.
You can stick it anywhere you want - the only thing necessary is that it gets called in code, before you call Mapper.Map<Product,ProductViewModel>.
E.g.
public static void main()
{
Mapper.Register<Product,ProductViewModel>();
}
is functionally the same as
public static void main()
{
RegisterMapping();
}
public static void RegisterMapping()
{
Mapper.Register<Product,ProductViewModel>();
}
If you want to map one class member to another class member with a different name, you can specify it with Member mapping.
Mapper.Register<Product, ProductViewModel>()
.Member(dest => dest.efgh, src => src.abcd);
If you want to apply special conversion rules, you can specify that with a Function mapping - e.g. you want the price in the ProductViewModel to be 2x the price of the product :
Mapper.Register<Product, ProductViewModel>()
.Function(dest => dest.Price, src => src.Price*2);
Any customisation that you make to the mapping should be done at the time you register the mapping, and has to be done on a Member-by-Member basis AFAIK.
If there's anything else specific that you need help with, leave a comment.

Joomla - Clear definition of JTable and JModelBase class?

I am making a Joomla 3.2 component by following the Lendr tutorial. They seem to add all of the database columns to their model as protected fields (use helper get/set functions to manipulate them) and CRUD operations as functions. Their table class only contains a constructor:
function __construct( &$db ) {
parent::__construct('#__lendr_books', 'book_id', $db);
}
When they are getting or saving an item, they return an instance of their table class rather than an updated version of the model e.g. if you saved a new item, the protected ID field on the model would be zero, but the ID on the returned table object would be non-zero.
So to me, it doesn't make sense to put all of the columns on the model and it would be better to explicitly declare them on the table class, or keep them updated on the model and don't return any table objects.
Components built into Joomla aren't using the new MVC convention and seem to be all over the show with where to but the CRUD operations.
Is there a clear definition of what the Model should do and what the Table should do in Joomla 3.2 using the non-legacy MVC classes?
It appears to be like this:
JTable Seems to be similar to Ruby on Rails' ActiveRecord::Base. It models the database and there is not really a need to put anything extra in here besides a constructor which declares the table name and primary key and possibly override some methods e.g. check. Basic CRUD operations are provided by JTable which will usually be called by your class that extends JModelBase.
function __construct( &$db ) {
parent::__construct('#__my_table', 'id', $db);
}
JModelBase handles the business logic of your model as well as preparing queries (which will often return the corresponding JTable values. The controller should always deal directly with this and not JTable.
In both cases there is not a need to explicitly add the database columns as properties on the class (just like in Rails).

ViewModel classes VS defining an Exclude Bind list on the domain class

I have a model class named Server, it contains many navigation properties and properties, which I want to prevent users from binding it. So I find two approaches of doing so to avoid over-posting attacks.
The first approach is to go to each model class and define an Exclude Bind list , with all the properties and navigating properties that should not be bind by users , as follow:-
[MetadataType(typeof(TMSServer_Validation))]
[Bind(Exclude = "Technology,IT360SiteID, VirtualMachines, TMSServer1,DataCenter,OperatingSystem,Rack,ServerModel,TechnologyBackUpStatu,TechnologyRole,TechnologyStatu ")]
public partial class Server {
}
}
The second approach is to create a view model class , with only the properties that can be modified by users as follow:-
public class ServerViewModel
{
public int ServerSize { get; set; }
[Required]
public String OperatingSystem { get; set; }
public String Commnet { get; set; }
}
I find that the first approach is faster to implement , as I only need to define the Exclude list, while the second approach will require me to create view-model class for each of the domain classes. So which approach is recommended to use and why ?
Thanks
Over-posting occurs due to the default model binder not knowing which fields you actually included in the form.
It will try to map all values in the request to object. Attackers can use your form to add additional fields to
query strings/form post data and add properties as part of the request. The default model binder won't
know the difference. Your Server class will deactivate once the mapping is complete and the update is processed.
To prevent over-posting, set the annotation to include fields in the binding, or create a ViewModel like you mentioned in your code.
So which approach is recommended to use and why ?
Both annotation and ViewModel allow binding only on specified fields, but when you use ViewModel you will not bind against business objects or entities, and you will only have properties available for the input you expected.
Once the model is validated, you can then move values from the input model to the object you used in the next layer.
k. Soctt Allen has a good article about which approach is better, you can take a look at by the following link:
http://odetocode.com/blogs/scott/archive/2012/03/11/complete-guide-to-mass-assignment-in-asp-net-mvc.aspx
It's difficult to tell without seeing the rest of your code, but in general I'd say using the ViewModel is probably a better approach for the following reasons:
You separate your view from your business logic
It is safer. If in the future someone adds a property on Server and forgets the Bind-exclude, you're exposed to over-binding without knowing it. If you use the ViewModel-approach you have to explicity add new properties
Maybe this question is a little bit ambiguous because the answers are going to be based on opinions or something. But I'll try to answer it the best I can and indeed is kind of my opinion. So this is the way I see it:
First approach (Bind attribute): Is faster to implement because you only need to add on your class the name of the property you don't want to expose, but the problems comes when you want your class to exclude some properties for one feature and other properties for another feature, and you can't add fields and sometimes in MVC, the views need more fields that the ones provided by the model class and then you're gonna need to use ViewBag or something else. This approach is very handy for fast and smalls projects, but I still don't like to use ViewBag (For aesthetics reasons)
Second approach (ViewModels): Is more work, and more time but at the end (again in my opinion) you get a cleaner and ordered code and you don't need to use the ViewBag, because you can have the perfect object to send to the view depending on what this View needs, so if you a have an object with different views, again depending on the needs, they could share the same ViewModel or they could have a ViewModel for each one. If you have a solution or a big web project, this approach is going to be very handy to keep an ordered code.
Let me know.

Repository pattern with simple select stored procedure

I have implemented the repository pattern using the following generic interface.
public interface IRepository<T> where T : class
{
IQueryable<T> All { get; }
IQueryable<T> AllIncluding(params Expression<Func<T, object>>[] includeProperties);
T Find(int id);
void InsertOrUpdate(T updateObject);
void Delete(int id);
void Save();
}
I then create the individual repositories and call them from my service layer.
I have a table in my database that is populated with the last date that one of our data feeds runs (it will only ever contain one record). All I need to do is get this date from the database. What is a good way to do this? Surely creating a repository for this simple read only table is overkill? Should I create a function or stored proc in the database to return this date and if I do how would it fit in with the repository pattern?
You shouldn't inherit from the general IRepository<T> interface because most of those methods won't make any sense.
But since you already state that you could use a stored procedure, a LINQ query or maybe even esql it would still be a good idea to encapsulate the data retrieval. What if you want to change the mechanism or apply some caching?
Also think about unit testing, your code depends on this 'last date', so in your unit tests you want to be able to supply different dates. A mockable repository will be the easiest.
Maybe you can add the LastModificationDate as a function to your ObjectContext. Then you have on single point of access and in a FakeObjectContext you can return specific dates for testing purposes.
If you can use an abstract for the repository definition rather than an interface, you can add the date-code directly to the abstract and have it inherited by all your repositories.

Remove field in wsdl in Asp.net webservice

I'm generating dto classes with a template engine and would like to exclude some properties in an asmx webservice, what, if possible, is the best way to do this?
Ex:
[WebMethod]
public ProductPackages GetPackages()
{
ProductPackages packages = new ProductPackages();
packages.Packages.add(new PackageDTO());
return packages;
}
The PackageDTO contains some properties that's not relevant for this service.
But as the class can be regenerated any time i can't apply [XmlIgnore] to the fields.
So I'm looking for a way to apply a "exclude list" without touching the actual class.
Above is just an example, the template engine generates dto's for all tables in a given project, and I would like to be able to use them in services without needing to maintain a big bunch of nearly identical classes.
Just hit the same problem. You can exclude fields by marking them as internal.
public class Order
{
public double OrderPrice;
internal double ProfitMargin;
internal string TheTruthAboutThisCustomer;
}
If you don't want to return a field or property, then don't have it in the object you return! It's as simple as that.

Resources