Ideas to create a unique identifier in firemonkey - firemonkey

I have been creating unique ids in my windows app and now that we are moving partly to mobile I am looking for a way to generate a unique id to be used as a primary key value in database work.
Does anyone have a way to do this in FireMonkey that they could share?
Thanks
John

You can use GUID like Tom say :
uses
SysUtils;
class function TPrimaryKey.GetKey: string;
begin
// remove { }
// ex: 5b477ddd-0178-43a4-815a-08b3e81ef68e
Result := TGUID.NewGuid.ToString().Replace('{', '').Replace('}', '');
end;

Related

How to get the indexvalue of a column with a relation set in QSqlRelationalTableModel?

In QsqlRelationalTableModel foreign keys are resolved to human readable strings, if a relation for the column containing a foreign key is set. In my application stationids are resolved to stationnames.
For some purposes i need the stationid too. QsqlRelationalTableModel.data() or QsqlRelationalTableModel.itemData() only return the displayValue (for displayrole as well as for editrole). How can i get the corresponding foreign key (indexValue)?
QsqlRelationalTableModel.relationModel() returns a QSqlTableModel object for accessing the table for which column is a foreign key.
http://doc.qt.io/qt-5/qsqlrelationaltablemodel.html#relationModel
By the setFilter() method of relationModel() the corresponding id (indexValue) can be found, if the displayValue is unique:
rm = self.relationModel(<index column>)
f = '<columnname> = "{}"'.format(<displayvalue>)
rm.setFilter(f)
id = rm.data(rm.index(0,0))
I mean you can change qsqlrelationaltablemodel.cpp file like this:
QString QSqlRelationalTableModel::selectStatement() const
......
//!!! my
fList.append(QLatin1String(", "));
fList.append(relTableAlias);
fList.append(QLatin1String("."));
fList.append(relation.indexColumn());
fList.append(QLatin1String(" as "));
fList.append(relation.tableName());
fList.append(QLatin1String("_"));
fList.append(relation.indexColumn());
I'v tested it on Qt 4.8.1.
Second variant to get you wish right result is to create own class inherited by QSqlTableModel that make as you need.
First you have to reimplemented selectStatement function and create your own behavier.
Here is a beta version of QSqlRelationalTableModelMod1 class for example:
https://kkmspb.ru/development/Qt/database-sql/Extended-Qt/QSqlRelationalTabelModelMod1/
Unfortunetly by russian only.

Specified cast is not valid.linq query c#

I have a table name LibraryInfo with these columns
[libraryId] [smallint] IDENTITY(1,1) NOT NULL,
[libraryName] [nvarchar](200) NOT NULL,
[mId] [smallint] NOT NULL,
[description] [nvarchar](300) NULL,
[updatedBy] [int] NOT NULL,
[updatedAt] [datetime] NOT NULL
I have designed a dbml file to access this table and create a method as follows:
public List<LibraryInfo> GetLibraryInfos()
{
var context = new BookDataClassesDataContext(){ ObjectTrackingEnabled = false };
return context.LibraryInfos.ToList();
}
when I call this method 'return context.LibraryInfos.ToList();' shows me 'specified cast is not valid'.
Is there anyone to help me.
You probably changed one of the column data types in your table or view after importing the table/view into your linq model.
Just re-import it so the data types of the auto generated model are the same as the db structure.
The problem seems to be related to the data type you are using. I recommend to use smallint rather than int. I had a similar some time ago, and later realized that querying tables with "int" data type causes the exact same problem. I changed int to Int16 and the problem was solved.
My former answer was obviously not correct. But:
You seem to have a mismatch of types here. ToList() on the context.LibraryInfos table would return a list of LibraryInfos objects (List<LibraryInfos>) instead of List<LibraryInfo>. So either your method needs to be declared as
public List<LibraryInfos> GetLibraryInfos()
or the code that returns the items needs to be changed to
return context.LibraryInfo.ToList();
This really depends on which one you want to return.
On your comment to your question:
context.LibraryInfo.ToList(); gives me error that dbml file does not contain a definition for LibraryInfo
Obviously you only have a LibraryInfos table in your data context. This means that you need to change your method return type to List<LibraryInfos>:
public List<LibraryInfos> GetLibraryInfos()
So the method now reads
public List<LibraryInfos> GetLibraryInfos()
{
var context = new BookDataClassesDataContext(){ ObjectTrackingEnabled = false };
return context.LibraryInfos.ToList();
}
Every item you get from the table has the type that matches the table name, as the LibraryInfos table is actually a collection of items of type LibraryItems.
You may have created a LibraryInfo class just because the compiler complained it didn't exist - you need to decide whether you can delete that from your project (look in solution explorer for LibraryInfo.cs file). But you can not cast between an item from the LibraryInfos table and that LibraryInfo class.

What is the right way to get Unique Identifier of windows phone 7?

Currently i am using the following methods. I am not sure if this is the correct way to identify each unique phone (doesn't need to have same sim card). For android there is a imei phone
public static String GetDeviceUniqueID()
{
object DeviceUniqueID;
byte[] DeviceIDbyte = null;
if (DeviceExtendedProperties.TryGetValue("DeviceUniqueId", out DeviceUniqueID))
DeviceIDbyte = (byte[])DeviceUniqueID;
string DeviceID = Convert.ToBase64String(DeviceIDbyte);
return DeviceID;
}
Yes , it is the only way to get the unique device identifier ...
Downt forget to include the necessary value in WMAppManifest.xml . If it is not found , there will be an exception as described in the below URL...
http://www.ginktage.com/2011/05/how-to-get-the-uniqueid-of-the-windows-phone-device-using-c/
That seems to be the suggested way from the stuff that I have read to date.

Calling a function with user defined type parameters (Oracle ODP.NET)

I'm using a function :
fu_has_permissions(udt_person('johny','superman'),'fly_away')
udt_person is a user defined type :
create or replace TYPE udt_person AS OBJECT
(name VARCHAR2(3),
id VARCHAR2(18));
I want to use bind variables whan calling this function, but i'm not really sure what am i doing wrong ... Here's the code :
......
OracleParameter udtPersParam = new OracleParameter();
udtPersParam.ParameterName = ":pUdtPers";
udtPersParam.UdtTypeName = "UDT_PERS";
string[] paramValues = { name, id };
udtPersParam.Value = paramValues;
OracleParameter pAction = new OracleParameter(":pAction", OracleDbType.Varchar2, 255);
pAction.Value = action;
parameters.Add(udtPartParam);
parameters.Add(pAction);
try
{
_loginOdr = DBFacade.ExecuteSelectQuery("select fu_has_permissions(:pUdtPart, :pAction) from dual", parameters);
}
Thanks!
the udt type must be a class that implements
IOracleCustomType
and/or IOracleCustomTypeFactory, IOracleArrayTypeFactory
unfortuntately you cannot just create a string array and pass it in
look in the odp.net samples that come with the odp installation
%ora_home%\client_1\odp.net\samples\4\UDT
also check out these links for samples and walkthroughs
http://developergeeks.com/article/35/working-with-user-defined-type-oracle-udt-and-custom-type-using-odp-net-11g
http://www.codeproject.com/KB/database/ORACLE_UDT.aspx
and
http://st-curriculum.oracle.com/obe/db/hol08/dotnet/udt/udt_otn.htm
Don't know anything about ODP.Net really, but the error suggests that it doesn't like you trying to use a string array as the value for an Oracle parameter. Which doesn't sound unreasonable.
A quick google of 'odp.net object varchar2' gave this OTN forum post as the first result; it includes an example of using an object about half-way down, including converting to and from Oracle object types.
if I were you I'd have a look at the ODP add-in to Visual Studio. With this you can connect to your database, select a UDT on the database, and "Generate Custom Class" to get a .net class you can use.
Look inside the class and you'll see what Harrison means. Pay particular attention to the OracleObjectMappingAttributes on top of the properties, and the overrides of To/FromCustomObject.
When you construct your OracleCommand, the OracleParameter.Value needs to be a class of this type.
That should get you started at a high level. A word of warning, though. The code generated by ODP is ugly to say the least - we're on the point of ditching all ODP-generated classes in our own scenario. But you'll need to understand what things like IOracleCustomType, IOracleCustomTypeFactory, IOracleArrayTypeFactory, INullable are before you'll be in a position to do this.
Incidentally since your specific question surrounds arrays, you might want to look at Oracle NTYPEs here, rather than TYPEs.

LINQ to SQL -

I'm attempting to use LINQ to insert a record into a child table and I'm
receiving a "Specified cast is not valid" error that has something to do w/
the keys involved. The stack trace is:
Message: Specified cast is not valid.
Type: System.InvalidCastException
Source: System.Data.Linq TargetSite:
Boolean
TryCreateKeyFromValues(System.Object[],
V ByRef) HelpLink: null Stack: at
System.Data.Linq.IdentityManager.StandardIdentityManager.SingleKeyManager2.TryCreateKeyFromValues(Object[]
values, V& v) at
System.Data.Linq.IdentityManager.StandardIdentityManager.IdentityCache2.Find(Object[]
keyValues) at
System.Data.Linq.IdentityManager.StandardIdentityManager.Find(MetaType
type, Object[] keyValues) at
System.Data.Linq.CommonDataServices.GetCachedObject(MetaType
type, Object[] keyValues) at
System.Data.Linq.ChangeProcessor.GetOtherItem(MetaAssociation
assoc, Object instance) at
System.Data.Linq.ChangeProcessor.BuildEdgeMaps()
at
System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode
failureMode) at
System.Data.Linq.DataContext.SubmitChanges(ConflictMode
failureMode) at
System.Data.Linq.DataContext.SubmitChanges()
(.....)
This error is being thrown on the following code:
ResponseDataContext db = new ResponseDataContext(m_ConnectionString);
CodebookVersion codebookVersion = db.CodebookVersions.Single(cv => cv.VersionTag == m_CodebookVersionTag);
ResponseCode rc = new ResponseCode()
{
SurveyQuestionName = "Q11",
Code = 3,
Description = "Yet another code"
};
codebookVersion.ResponseCodes.Add(rc);
db.SubmitChanges(); //exception gets thrown here
The tables in question have a FK relationship between the two of them.
The parent table's column is called 'id', is the PK, and is of type: INT NOT NULL IDENTITY
The child table's column is called 'responseCodeTableId' and is of type: INT NOT NULL.
codebookVersion (parent class) maps to table tblResponseCodeTable
responseCode (childClass) maps to table tblResponseCode
If I execute SQL directly, it works. e.g.
INSERT INTO tblResponseCode
(responseCodeTableId, surveyQuestionName, code, description)
VALUES (13683, 'Q11', 3, 'Yet another code')
Updates to the same class work properly. e.g.
codebookVersion.ResponseCodes[0].Description = "BlahBlahBlah";
db.SubmitChanges(); //no exception - change is committed to db
I've examined the variable, rc, after the .Add() operation and it does, indeed, receive the proper responseCodeTableId, just as I would expect since I'm adding it to that collection.
tblResponseCodeTable's full definition:
COLUMN_NAME TYPE_NAME
id int identity
responseCodeTableId int
surveyQuestionName nvarchar
code smallint
description nvarchar
dtCreate smalldatetime
dtCreate has a default value of GetDate().
The only other bit of useful information that I can think of is that no SQL
is ever tried against the database, so LINQ is blowing up before it ever
tries (hence the error not being a SqlException). I've profiled and verified
that no attempt is made to execute any statements on the database.
I've read around and seen the problem when you have a relationship to a non PK field, but that doesn't fit my case.
Can anyone shed any light on this situation for me? What incredibly obvious thing am I missing here?
Many thanks.
Paul Prewett
Post up the schema of the parent table.
if you look here, some other people have had your problem.
http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=3493504&SiteID=1
It appears that Linq2SQL has trouble mapping some foreign keys to some primary keys. One guy had a resolution, but I think you are already mapping to an IDENTITY column.
Since the database isn't being called I think you have to look at the mappings linq to sql is using. What does the Association look like? There should be an Association on both the parent and child classes.
Take a look at the linq to sql Association between the two classes. The Association should have a ThisKey property. The cast that is failing is trying to cast the value of the property that ThisKey points to, I think.
As far as I can tell there can be a problem when there is more than one key and the type of the first key does not match the type that ThisKey points too. I'm not sure how linq would determine what the first key is.
From the looks of it you only have one key and one foreign key so that shouldn't be the problem, but the designer, if you are using it, has been known to get creative.
I'm pretty much guessing, but this looks like something I've seen before.
Is this an example of this bug? If so, try running your code in .NET 4.0 now that the beta is out.
If, like me, you aren't ready to start using the beta, you may be able to work around the problem. The issue seems to be that LINQ does not properly support relationships defined on non-primary key fields. However, the term "primary key" does not refer to the primary key defined on the SQL table, but the primary key defined in the LINQ designer.
If you dragged your tables into the designer, then Visual Studio automatically inspects the primary key defined in the database and marks the corresponding class field(s) as "primary keys". However, these do not need to correspond to each other. You can remove the key Visual Studio chose for you, and pick another field (or group of fields). Of course, you need to make sure this is logical (you should have a unique constraint in the database on the field/fields you choose).
So I had 2 tables/classes related to eachother using an alternative key. The parent table had 2 keys: a surrogate primary key defined as an int, and an alternative natural key defined as a string. In the LINQ designer, I had defined the association using the alternative key, and I experienced the InvalidCastException whenever trying to update that association field on the child object.
To work around this, I went into the LINQ designer, selected the int, and then changed the Primary Key property from True to False. Then I chose the string, and set it's Primary Key property to True. Recompiled, retested, and the InvalidCastException is gone.
Looking at your screen shot it looks like you may be able to fix your issue by changing the LINQ primary key on ResponseCode from ResponseCode.ID to ResponseCode.ResponseCodeTableID
ResponseCode rc = new ResponseCode()
{
SurveyQuestionName = "Q11",
Code = 3,
Description = "Yet another code"
};
and:
INSERT INTO tblResponseCode
(responseCodeTableId, surveyQuestionName, code, description)
VALUES (13683, 'Q11', 3, 'Yet another code')
Are not the same, you are not passing in the foreign key reference. Now, I'm huge n00b at LINQ2SQL, but I'd wager that LINQ2SQL is not smart enough to do that for you, and it expects it as the first parameter of the anonymous dictionary, and is trying to cast a string to an integer.
Just some ideas.
This block:
codebookVersion.ResponseCodes.Add(rc);
db.SubmitChanges(); //exception gets thrown here
Can you try InsertOnSubmit instead of Add? i.e.
codebookVersion.ResponseCodes.InsertOnSubmit(rc);
I think Add is not meant to be used to insert records if my memory serves me right. InsertOnSubmit is the one to use.
To try and narrow down the culprit.
Have you tried replacing the anonymous dictionary with something like:
ResponseCode rc = new ResponseCode();
rc.SurveyQuestName = "Q11";
rc.Code = 3;
rc.Description = "Yet Another Code";
I've yet to really work with .NET 3.5 yet (day job is still all 2.0), so I'm wondering if there is an issue with passing the data using the anonymous dictionary (The cases don't match the SQL Columns for one).
Yea, I've read that and other posts, but it always seems to involve someone linking up to a field that simply has a unique contraint. Or in this guy's case (which does sound exactly like mine), he didn't get a solution.
Here's the parent table:
tblResponseTable definition (which maps to CodebookVersion)
COLUMN_NAME TYPE_NAME
id int identity
versionTag nvarchar
responseVersionTag nvarchar
versionTag does have a unique contraint on it, but that's not represented anywhere that I can see in the LINQ-to-SQL stuff - and since nothing ever goes to the database... still stuck.
Mike, I hear you. But no matter where I look, everything looks correct. I've checked and rechecked that the ResponseTableId is an int and that Id is an int. They're defined as such in the designer and when I go look at the generated code, everything again appears to be in order.
I've examined the associations. Here they are:
[Table(Name="dbo.tblResponseCode")]
public partial class ResponseCode : ...
...
[Association(Name="CodebookVersion_tblResponseCode", Storage="_CodebookVersion", ThisKey="ResponseCodeTableId", OtherKey="Id", IsForeignKey=true)]
public CodebookVersion CodebookVersion
{
...
}
[Table(Name="dbo.tblResponseCodeTable")]
public partial class CodebookVersion : ...
...
[Association(Name="CodebookVersion_tblResponseCode", Storage="_ResponseCodes", ThisKey="Id", OtherKey="ResponseCodeTableId")]
public EntitySet<ResponseCode> ResponseCodes
{
...
}
And a screenshot of the association in case that will help:
Any further thoughts?
ResponseCode rc = new ResponseCode()
{
CodebookVersion = codebookVersion,
SurveyQuestionName = "Q11",
Code = 3,
Description = "Yet another code"
};
db.ResponseCodes.InsertOnSubmit(rc);
db.SubmitChanges();
You may want to check to see that any fields in your database tables which are set by the db server when inserting a new record have that reflected in the Linq to SQL diagram. If you select a field on the Linq to SQL diagram and view its properties you will see a field called "Auto Generated Value" which if set to true will ensure all new records take on the default value specified in the database.
LINQ to SQL has been deprecated, FYI - http://blogs.msdn.com/adonet/archive/2008/10/29/update-on-linq-to-sql-and-linq-to-entities-roadmap.aspx.
I ran into a very similar problem. I'll link you over to my wordy post: http://forums.asp.net/p/1223080/2763049.aspx
And I'll also offer a solution, just a guess...
ResponseDataContext db = new ResponseDataContext(m_ConnectionString);
CodebookVersion codebookVersion = db.CodebookVersions.Single(cv => cv.VersionTag == m_CodebookVersionTag);
ResponseCode rc = new ResponseCode()
{
ResponseCodeTableId = codebookVersion.Id,
SurveyQuestionName = "Q11",
Code = 3,
Description = "Yet another code"
};
db.ResponseCodes.InsertOnSubmit(rc);
db.SubmitChanges();
Somewhere in your object graph there is a conversion error, the underlying data model (or the Linq To SQL model) has changed. This is typically something like NVARCHAR(1) -> CHAR when it should be STRING, or something similar.
This error is not fun to hunt down, hopefully your object model is small.
We had a similar problem, caused by using non-integer keys. Details and hotfix number are here: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=351358

Resources