Does Codefluent Entities support method overloading? - codefluent

I want to create 2 methods with the same name, same return type, but different parameters.
When I attempted this using the Model the following happened:
No error message was immediately generated when adding the second method to the model.
The second method did not appear in the GUI for the Model.
Both methods do appear in the XML file generated by the Model.
When I attempt to build the model I got the following error message:
Error 1 CF0075: Procedure
'_PR01_PayrollEmployeeFile_LoadBySocialSecurityNumber' for method
'LoadBySocialSecurityNumber(System.String socialSecurityNumber,
System.String companyCode)' with body 'LOAD(string
socialSecurityNumber, string companyCode) RAW' already exists. Try to
change method name or method
persistenceName. 0 0 Amikids.DataProWarehouse.Model

To the good support people at Softfluent: Give me 24 hours and check back to make sure the following solution fully works and I don't have any other issues.
I think I have the solution but have not fully tested and noticed something quirky in the XML after I did a build, but suspect I may have corrupted the XML file and don't have time to fully explore.
The solution (I think):
Set the persistenceName in the XML file. The persistenceName corresponds to the generated stored procedure name.
<cf:method name="TestMethod" body="LOAD(string x) ORDER BY FirstName" persistenceName="TestMethod1" />
<cf:method name="TestMethod" body="LOAD(string x, string y) ORDER BY LastName" persistenceName="TestMethod2" />

Related

How to specify EF byte[] in code first longer than 8000 bytes?

I am using EF 6.1.3. Using code first sets a byte[] property in an entity to max. 8000 bytes. Any attempt to make it greater, that is MAX, fails.
HasMaxLength(null) (yes, the parameter is int?) still sets it to 8000, HasMaxLength(int.MaxValue) or any other value greater than 8000 makes EF throw System.Data.Entity.Core.MetadataException:
Schema specified is not valid. Errors: (0,0) : error 0026: MaxLength
'2147483647' is not valid. Length must be between '1' and '8000' for
'varbinary' type.
SQL server 13.0.2151 (mssqllocaldb) allows for varbinary(max):
This limit seems too severe to me. Trying to find a reason why it is imposed does not yield a good reason for this too. So, my question is
How a byte[] can be mapped to varbinary(max) in EF code first?
PS: The property is also 'required', but I am not sure if an optional property may be set to varbinary(MAX) either. Anyway, i have not tested this case since it does not make much sense to me.
Despite the multiple articles that states the solution is to add the following attribute
[Column(TypeName="image")]
byte[] Photo { get; set; }
I found the correct approach to be, adding instead this attribute
[MaxLength]
public byte[] Photo { get; set; }
With the Column(TypeName) recommendation I'll end up getting the following error with SQLCE:
The field Photo must be a string or array type with a maximum length of '4000'
Well, I found a workaround to this. Specifying HasColumnType("image") solves the problem, but I still think that EF must allow for specifying varbinary(max) as well.
Moreover, not all binary files are images. ;)
And still part of the question remains unanswered, so I will put it this way:
Why a byte[] property cannot be mapped to varbinary(max) in EF code first?
Any comments (or answers of course) are welcome. Thanks in advance.
EDIT (as per comment by Gert): leaving the property without any specs makes EF generate varbinary(max). Surprisingly simple!
It is possible.
Fluent API
.IsMaxLength()
Before you want to update the database take a look in the filename which is generated after you use "add-migration filename"
If you see a method "CreateTable" and see that a field which should te be a binary type with a lenght of MAX, it can be generated as c.Binary(maxLength: 8000), remove the parameter maxLength at all and then use update-database and after that you can check the created table in the SQL server database!

Loading a file from a parameter in Jasper

I'm new to writing jasper reports (and SQL in general). We are trying to load an RTF or HTML file as a disclosure at the end of a report. The way we are doing this is by selecting the name of the file ("Disclosure") in part of the SQL:
SELECT
....
'Disclosure' as Disclosure
FROM
...
And then, obviously, there is a field for this:
<field name="Disclosure" class="java.lang.String"/>
At the end, in the summary section of the report, we use the loadfile utility:
<textFieldExpression class="java.lang.String"><![CDATA[JasperFileRuntimeUtility.loadFile($F{Disclosure}, $P{REPORT_PARAMETERS_MAP})]]></textFieldExpression>
If the report returns data, this works beautifully. But if the result of the original query does not return any records, then the disclosure is not included in the report (since the result of the query is nothing, obviously).
I thought we could easily work around this by providing the "Disclosure" as a Parameter, but when I change that to $P instead of $F. I get an error about invalid io file type.
I also tried creating a Variable and setting that $V to the value of the $P we are passing in, but no luck there either.
Is there a load file type of utility that will load a parameter like we are doing with the field? Any other suggestions?
Appreciate the help!!!
I have understood you question better now so I edit the answer, you are calling
JasperFileRuntimeUtility.loadFile($F{Disclosure}, $P{REPORT_PARAMETERS_MAP})
you have no clue what function is this but you know that if you pass the String "Disclosure" it works.
The class JasperFileRuntimeUtility is within your library (its not an official jasper report function), try to search your project or your libraries.
It has a static method public static String loadFile(String value, Map<?,?> map)
Calling the metod with where $F{Disclosure} = "Disclosure"
JasperFileRuntimeUtility.loadFile($F{Disclosure}, $P{REPORT_PARAMETERS_MAP})
or
JasperFileRuntimeUtility.loadFile("Disclosure", $P{REPORT_PARAMETERS_MAP})
will not make any different the result will be the same (since the method have no other idea then with what parameters you call it).
Normally also calling with a $P{Disclosure} = "Disclosure"
JasperFileRuntimeUtility.loadFile($P{Disclosure}, $P{REPORT_PARAMETERS_MAP})
would be the same, but since the the parameter map is passed the function can see this parameter and maybe do something else...
More likely however since the parameter map is passed to function, you may have scriptlet or other calls that set static fields, and when you have no result the call to loadFile is not working since these static fields have not been set.
So if it is not working passing "Disclosure" this is most certainly the case..
Have fun!

Get statuscode text in C#

I'm using a plugin and want to perform an action based on the records statuscode value. I've seen online that you can use entity.FormattedValues["statuscode"] to get values from option sets but when try it I get an error saying "The given key was not present in the dictionary".
I know this can happen when the plugin cant find the change for the field you're looking for, but i've already checked that this does exist using entity.Contains("statuscode") and it passes by that fine but still hits this error.
Can anyone help me figure out why its failing?
Thanks
I've not seen the entity.FormattedValues before.
I usually use the entity.Attributes, e.g. entity.Attributes["statuscode"].
MSDN
Edit
Crm wraps many of the values in objects which hold additional information, in this case statuscode uses the OptionSetValue, so to get the value you need to:
((OptionSetValue)entity.Attributes["statuscode"]).Value
This will return a number, as this is the underlying value in Crm.
If you open up the customisation options in Crm, you will usually (some system fields are locked down) be able to see the label and value for each option.
If you need the label, you could either do some hardcoding based on the information in Crm.
Or you could retrieve it from the metadata services as described here.
To avoid your error, you need to check the collection you wish to use (rather than the Attributes collection):
if (entity.FormattedValues.Contains("statuscode")){
var myStatusCode = entity.FormattedValues["statuscode"];
}
However although the SDK fails to confirm this, I suspect that FormattedValues are only ever present for numeric or currency attributes. (Part-speculation on my part though).
entity.FormattedValues work only for string display value.
For example you have an optionset with display names as 1, 2, 3,
The above statement do not recognize these values because those are integers. If You have seen the exact defintion of formatted values in the below link
http://msdn.microsoft.com/en-in/library/microsoft.xrm.sdk.formattedvaluecollection.aspx
you will find this statement is valid for only string display values. If you try to use this statement with Integer values it will throw key not found in dictionary exception.
So try to avoid this statement for retrieving integer display name optionset in your code.
Try this
string Title = (bool)entity.Attributes.Contains("title") ? entity.FormattedValues["title"].ToString() : "";
When you are talking about Option set, you have value and label. What this will give you is the label. '?' will make sure that the null value is never passed.

Entity Framework .Include does not support paths with more than 8 dot-separated names

I've opened a bug on Microsoft Connect for this, but no response (see edit below for their response) in a long while. So here it goes:
When trying to request an entity framework with its relation using the "Include" function in the linq query, it's impossible to request a relation through a path of more than 8 steps (8 . dot characters in the path). This prevents me from completing some of my dynmically generated queries that require access to more than that level of redirection.
Instead of completing the query successfully I get the following exception:
"Foo.Bar.Baz...(some more path string here)", the current limit of "8" is insufficient.
at System.Data.Common.MultipartIdentifier.IncrementStringCount(String name, String[] ary, Int32& position, String property)
at System.Data.Common.MultipartIdentifier.ParseMultipartIdentifier(String name, String leftQuote, String rightQuote, Char separator, Int32 limit, Boolean removequotes, String property, Boolean ThrowOnEmptyMultipartName)
at System.Data.Objects.Span.ParsePath(String path)
at System.Data.Objects.Span.Include(String path)
at System.Data.Objects.Span.IncludeIn(Span spanToIncludeIn, String pathToInclude)
Has anyone figured why this is so, or a way around this? Looking at the code (with Reflector) of ParsePath it seems that they hard-coded the magic number 8 in there...
UPDATE: Microsoft's response:
Thank you for raising this issue. We plan to remove the limit of the number of elements in an Include path in the next release.
UPDATE 2: Despite Microsoft's response quoted above, the bug was not fixed in EF 4.1
UPDATE 3: According to Microsoft, should be fixed in .NET 4.5, but I didn't test the developer preview to see if it works.
probably fixed in latest .net 4.5
https://connect.microsoft.com/VisualStudio/feedback/details/640423/entity-framework-include-strings-are-arbitrarily-limited-to-a-path-of-depth-8#tabs
I have not seen this, but here are 2 possible work arounds:
Loop through the data and use Load for each row. Note this will create a call to the database for each row, so it is really slow.
Flatten the data in a view and then select from the view. This creates a lot of redundant data, so more memory and network use.

Entity Framework + Sql Anywhere 11 + Stored procedures

I have been playing with the EF in the last couple of days.
Our applications are based on SQL Anywhere 10 databases, and all our data access are done through stored procedures. Since EF is not supported by SA 10, I am testing EF with SA 11.
For this purpose i have create a small database with 2 tables and a couple of stored procedures (based on the nerddinner database from the asp.net mvc samples, see here )
I have created a model from the database, tables and stored procedures and did the necessary function imports.
I have a stored procedure with the following signature:
ALTER PROCEDURE "DBA"."get_dinner"( #dinner_id integer)
BEGIN
select dinner_id, title, event_date, description, hosted_by , contact_phone, address, country, latitude, longitude
from dba.dinners d
where d.dinner_id = #dinner_id
END
And the resulting function import code looks like this:
public global::System.Data.Objects.ObjectResult<dinner> get_dinner(global::System.Data.Objects.ObjectParameter dinner_id)
{
return base.ExecuteFunction<dinner>("get_dinner", dinner_id);
}
And that's the problem. Ideally, the code generated should accept an int parameter, instead of global::System.Data.Objects.ObjectParameter dinner_id
As far as I see, the edmx file has all the data it needs to interpret the parameter types correctly:
<Function Name="get_dinner" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="false" ParameterTypeSemantics="AllowImplicitConversion" Schema="DBA">
<Parameter Name="dinner_id" Type="int" Mode="InOut" />
</Function>
Am I missing something here? What else is needed in order to have a function import with the proper parameter type? Is this something you can correct by tweaking the edmx file, or is it a problem of the SA11 EF support implementation.
Hope someone can give me some further clues.
This is a known problem with InOut parameters and code gen for Function Imports.
We have been talking about making InOut parameters produce code like this:
public ObjectResults<dinner> get_dinner(ref int dinner_id);
Rather than what you have.
One thing to try is converting from an 'InOut' to an 'In' parameter. Code gen should then produce something like this:
public ObjectResults<dinner> get_dinner(int dinner_id);
The real question though is does it work if you call it?
Hope this background helps
Cheers
Alex