CSLA .NET

Vibrant discussion about CSLA .NET and using the framework to build great business applications.

Correct use of SmartDate in CSLA 4.2?

rated by 0 users
Answered (Verified) This post has 1 verified answer | 22 Replies | 1 Follower

Top 50 Contributor
163 Posts
gajit posted on Mon, Feb 27 2012 5:46 PM

I can;t find anything on the SmartDate type in the new eBooks?

What's the correct implementation in 4.2?

In 2.1, I  declared the properties as such:

Private mEFFECTIVEDATE as New SmartDate(False)

    Public Property EFFECTIVEDATE() As String
        Get
            CanReadProperty(True)
            Return mEFFECTIVEDATE.Text
        End Get
        Set(ByVal Value As String)
            CanWriteProperty(True)
            If mEFFECTIVEDATE <> Value Then
                mEFFECTIVEDATE.Text = Value
                ValidationRules.CheckRules("EFFECTIVEDATE")
                PropertyHasChanged()
            End If
        End Set
    End Property

Fetching the value I did as:

                mEFFECTIVEDATE = .GetSmartDate("EFFECTIVEDATE", mEFFECTIVEDATE.EmptyIsMin)

And passing as a datetime parameter to SQL I did:

               cm.Parameters.AddWithValue("@pdt_EffectiveDate", mEFFECTIVEDATE.DBValue)

Basically, In 4.2, I can't see how the emptyIsMin is handled in this version. When I read in a date field - which is NULL, update another field on the BO and save, the date field value becomes 1900-01-01 - that's not the required right...

Any ideas?

Thanks,

Graham 

 

Answered (Verified) Verified Answer

Top 10 Contributor
9,269 Posts
Verified by gajit

In the code I just posted, notice that LoadProperty takes a SmartDate value, not a string. The corresponding ReadProperty call would return a SmartDate.

That is the value you'd pass to your DAL, not a string. I am not seeing the issue here?

Rocky

All Replies

Top 10 Contributor
1,764 Posts
JonnyBee replied on Mon, Feb 27 2012 10:52 PM

Use the snippets supplied in the Support folder to define properties.

There you will find the "DefineACslaSmartDateProperty" snippet - shortcut "cslapropdt" and more.

For an overview of snippets and templates look at the CSLA CheatSheet available in the FAQ: http://www.lhotka.net/files/csla40/CSLA4CheatSheet.pdf

EmptyIsMin is typically set on the PropertyInfo (RegisterProperty) when supplying a default value for the backing field:

Public Shared ReadOnly StartDateProperty As PropertyInfo(Of SmartDate) = RegisterProperty(Of SmartDate)(Function(c) c.StartDate, Nothing, New SmartDate(EmptyValue.MinDate))

gajit:

Basically, In 4.2, I can't see how the emptyIsMin is handled in this version. When I read in a date field - which is NULL, update another field on the BO and save, the date field value becomes 1900-01-01 - that's not the required right...


That is the proper and expected behavior by SmartDate. It will however have .IsEmpty = True and DBValue = DBNull but the internal Date and Text will have a value (either min or max),

Jonny Bekkum, Norway CslaContrib Coordinator

Top 50 Contributor
163 Posts
gajit replied on Tue, Feb 28 2012 8:20 AM

Yes, I have that in my declaration.

But there is no code for the passing of the value as a parameter in the Dal.

In CSLA 2.x, we passed mMYDATE.DBVALUE, which for a blank smartdate value (the string property), would be NULL.

In CSLA 4, we don't use the private mMydate property, we pas the public MYDATE property.

I can't do a .AddWithValue("@Mydate", MYDATE.DBVALUE)

??

Top 50 Contributor
163 Posts
gajit replied on Tue, Feb 28 2012 9:17 AM

I see Rocky showed a solution here;

http://forums.lhotka.net/forums/p/10971/51044.aspx

BUT, is ReadProperty not a method from one of the base models such as BusinessBase?

Dim temp = ReadProperty(ScheduledDateProperty)
cmd.Parameters.AddWithValue("@ScheduledDate", temp.DBValue)

My data access code is in a separate Dal class, NOT in the class bo class and therefore ReadProperty cannot be accessed as a method????!!

How is this implemented?

Graham

Top 10 Contributor
1,764 Posts

Look at the Csla.Server.ObjectFactory class and make your data accsess class inherit from this or create a ObjectAccessor class.

Jonny Bekkum, Norway CslaContrib Coordinator

Top 50 Contributor
163 Posts
gajit replied on Tue, Feb 28 2012 11:03 AM

I can't???

My CodeDal class IMPLEMENTS ICodeDal. How can I inherit from Objectfactory?

Honestly.... it's like pulling teeth this version of the framework.... 2.x didn't require one to understand the inner workings of the framework, now the expectation is that the framework user has to implement a helper type as there if no clear guide on how to do it????

This is my biggest criticism of the current version - that the features are NOT fully documented. The eBook recommedndation is NOT to rollup your data access code into your business object a-la csla 2.x, instead suggesting use of one of the dal models, yet there is no supporting documentation to demonstrate how we implement surviving types like SmartDate.

This is a fundamental requirement for many CSLA 2 users, and I'm flabberghasted that it isn't covered concisely.

CSLA2 helped me develop applications, quickly and cleanly. So far, my progress has been stifled with vague references to 'this or that' and frankly I'm developing at a snail's pace.

Graham

Top 10 Contributor
1,764 Posts
JonnyBee replied on Tue, Feb 28 2012 11:26 AM

Implements and inherits is 2 different aspects. Your CodeDal can both inherit from one class and implement one or multiple interfaces.

Yes, there is more ways of coding the data access in Csla 3.x and Csla 4.

This is described in the Using CSLA4 Data Access ebook: chapter 4, 5 and 6:

Quote:

When the DAL is external, the data access invocation code is responsible for invoking the DAL to
get, save, or delete data. This invocation code might be in your DataPortal_XYZ methods, or it
might be in your factory object methods. Either way, the DAL must expose some formal interface
that can be invoked.

......

It is also the case that some code must interact with the private state and metastate of the
business object to get and set the object’s properties and metastate. As I’ve already discussed, this
can be done in a way that preserves encapsulation by using the DataPortal_XYZ methods, or it can
be done by breaking encapsulation with factory objects and the ObjectFactory base class.

I’ll cover all these concepts, starting with options for the DAL interface.

OR you could just add an extra property in your BO for use in the data access:

    [Browsable(false)]
    [Display(AutoGenerateField = false)]
    public SmartDate AssignedSmartDate
    {
      get { return GetProperty(AssignedProperty); }
      set { SetProperty(AssignedProperty, value); }
    }

 

Jonny Bekkum, Norway CslaContrib Coordinator

Top 50 Contributor
163 Posts
gajit replied on Tue, Feb 28 2012 11:54 AM

Without sounding blunt Jonny, how the heck does that help?

I've read the quoted passages a number of times, and frankly the excerpts do NOT demonstrate how to access the private state or metastate values in the business object.

I am using the datareader model of the Encapsulated Invoke. NOWHERE does it provide even a hint of a clue on how to access say, the private business value "MyDateProperty" from the Dal. I can only reference "MyDate"

If there are no examples in the book, and no-one is willing to show me a real-life code example of how I would implement it, then once again I've created another post that from my perspective remains "Unanswered".

Extremely frustrated.

 

Top 50 Contributor
163 Posts
gajit replied on Tue, Feb 28 2012 12:24 PM

Would I not want to make the "AssignedSmartDate" private?

 

Top 50 Contributor
163 Posts
gajit replied on Tue, Feb 28 2012 12:44 PM

That usage of AssignedSmartDate also causes my business object to become 'Dirty' after fetch.

 

 

 

Top 10 Contributor
1,764 Posts

I'd still prefer to use ObjectFactory and BypassPropertyChecks --> which makes properties and SetProperty behave as LoadProperty. 

Jonny Bekkum, Norway CslaContrib Coordinator

Top 50 Contributor
163 Posts
gajit replied on Tue, Feb 28 2012 2:04 PM

And i still have no clue.

Using a separate property to handle the data access isn't working. The BO is dirty when it loads - and yes, I'm using LoadProperty. I as Loadproperty by definition should ignore checks, then I shouldn't have to  

I have no idea how you implement ObjectFactory in the model that I have outlined in this post, so unless someone is kind enough to post a working solution to my problem, then I'll consider it yet another facet of CSLA4 that in my opinion leaves the developer in the dark. If I have to dig for every single change that has happened between version 2 and 4 it makes zero sense for me to adopt this framework, considering the amount of time undertaken.

I appreciate your efforts to educate me, but I have little time to dig deep into the "how it works" and was hoping for a working CSLA4 code snippet in response to my original CSLA2 working code snippet.

Graham

 

Top 10 Contributor
9,269 Posts

This surely isn't hard enough to be worthy of your anger, frustration, and corresponding outbursts (which I find less and less motivational - how much did you pay for my framework? It was free? Really? And once you've learned to build CSLA 4 style classes they run on every known .NET related platform? Wow that's a good value!!)

What am I missing from the following example? It has a SmartDate property, it uses an ObjectFactory, and the resulting object isn't dirty:

  class Program
  {
    static void Main(string[] args)
    {
      var obj = DataPortal.Fetch<Test>(123);
      Console.WriteLine(obj.Date);
      Console.WriteLine(obj.IsDirty);
      Console.ReadLine();
    }

  }

  [Serializable]
  [Csla.Server.ObjectFactory(typeof(TestFactory))]
  public class Test : BusinessBase<Test>
  {
    public static readonly PropertyInfo<SmartDate> DateProperty = RegisterProperty<SmartDate>(c => c.Date);
    public string Date
    {
      get { return GetPropertyConvert<SmartDate, string>(DateProperty); }
      set { SetPropertyConvert<SmartDate, string>(DateProperty, value); }
    }
  }

  public class TestFactory : Csla.Server.ObjectFactory
  {
    public Test Fetch(int id)
    {
      var result = new Test();
      using (BypassPropertyChecks(result))
      {
        LoadProperty(result, Test.DateProperty, new SmartDate("1/1/10"));
      }
      MarkOld(result);
      return result;
    }
  }

Rocky

Top 50 Contributor
163 Posts
gajit replied on Tue, Feb 28 2012 7:00 PM

My anger, frustration and "outbursts" are a culmination of issue after issue with implementing this framework and not finding sufficient coverage in the books.

I appreciate the investment is small, but you ghave to recognize that there is SOME expectation that the framework does what it has ALWAYS done - and if that has changed dramatically - which it has - provide documentation on how to do that. For the record, based on my CSLA2 experience, I would have paid significantly more for the latest version.

We're not ALL software engineers, otherwise we'd all be writing frameworks. I'm, a humble developer who has had success using the earlier versions of the framework, and now wants to maybe open some more doors by using the current technology. The simplest way for me to do that is to be given a code sample - as you have just done - rather than trying to "guess" my way around the various components of the new model.

I apologise for my "outburst", but as I didn't think my original post warranted anything more than a reworked example in CSLA4. (That was the purpose of me posting my CSLA2 code). Instead, I ended up in a downward spiral of trying to understand this, that and the other. That IS frustrating.

My original post revolved around the issue of not being able to access the private smartdate attributes of my string property when referenced in my Dal. I will review your example, and hopefully it wil translate to what I'm actually doing.

Thank you.

Graham

Top 50 Contributor
163 Posts
gajit replied on Tue, Feb 28 2012 7:15 PM

Nope, Sorry.

I guess I shall go back to the books.

Having selected the encapsulated invoke model using datareader, I don't understand where the "factory" class sits in my structure.

Maybe it's the terminology, but I thought "factory" implementation was a different model.

I have three distinct classes/interfaces when I'm building a BO;

IPersonDal - the interface in my DataAccess project that defines the dataaccess layer

PersonDal - in my DataAccess.SQL project that contains my Fetch, Insert, Update, etc methods, which implements IPersonDal and interacts with the database

PersonEdit - my BO that defines the properties of my object and contains the DataPortal_xxx methods

As I said, I'm going back to the books.

If it's not possible for me to do what I need to do using the encapsulated invoke model, I'd appreciate it if you could just let me know, so I'm not heading off on a wild goose chase.

Thanks,

Graham

 

 

Page 1 of 2 (23 items) 1 2 Next > | RSS

Copyright (c) 2006-2010 Marimer LLC. All rights reserved.
Email admin@lhotka.net for support.
Powered by Community Server (Non-Commercial Edition), by Telligent Systems