Using LongListSelector with a Deployed Database - linq-to-sql

I'm trying to create an app for Windows Phone 8 that displays data in a LongListSelector that's populated from a SQL CE database that's shipped with the app. I think I have the opening and reading from the database functions down, but I can't correctly use LINQ to SQL to group the data for the LLS.
I've got a database class with a table and corresponding columns. I'm using a helper class "KeyedList" to add a public name for the data from msdn sample code:
public class KeyedList<TKey, TItem> : List<TItem>
{
public TKey Key { protected set; get; }
public KeyedList(TKey key, IEnumerable<TItem> items)
: base(items)
{
Key = key;
}
public KeyedList(IGrouping<TKey, TItem> grouping)
: base(grouping)
{
Key = grouping.Key;
}
}
Then I've got my database context:
dB = new DataContext(DataContext.DBConnectionString);
Finally, here's the LINQ to SQL I'm trying to use:
var items =
from item in dB.TableName
orderby dB.ID
group item by dB.Generation into generation
select new <KeyedList<string,Item>(generation);
var allItems = new List<KeyedList<string, Item>>(items)
I've pretty much taken this code from the sample, but I can't get the grouping and ordering to work when creating allItems for binding to the LongListSelector. I keep getting invalid arguments error.
I'm very new at VB programming and appreciate all the help!

I found the issue. When creating the new Keyed list make sure to use the correct key type and item type. The key type will be the type of the data used by group by, and the item type is your DataContext. So in my case db.Generation is a string and the DataContext type is of type Item.

Related

SQLGrammar error when querying MySql view

When a run a GET request i get an exception o.h.engine.jdbc.spi.SqlExceptionHelper : Unknown column 'disburseme0_.reason_type' in 'field list' in stack trace even though i have configured the field correctly in the entity class. I have a Spring Boot SOAP interface that is querying a MySql database view. I have assigned one of the unique keys from the parent tables as the view Id in JPA.
Part of my entity class has:
#Entity
#Table(name="disbursement_payload")
public class Disbursement {
#Id
#Column(name="ID")
private long disbursementId;
#Column(name="ReasonType")
private String reasonType;
public long getDisbursementId() {
return disbursementId;
}
public void setDisbursementId(long disbursementId) {
this.disbursementId = disbursementId;
public String getReasonType() {
return reasonType;
}
public void setReasonType(String reasonType) {
this.reasonType = reasonType;
}
I have the view as:
CREATE VIEW disbursement_payload AS (
SELECT
iso_number AS Currency,
trans_desc AS ReasonType,
account_number AS ReceiverParty,
amount AS Amount
FROM m_payment_detail, m_loan_transaction
WHERE m_payment_detail.`id`= m_loan_transaction.`payment_detail_id` AND
m_payment_detail.`payment_type_id`=2
);
Is there something im missing , in the entity or view definition? I have read one of the comments here could not extract ResultSet in hibernate that i might have to explicitly define the parent schemas. Any assistance, greatly appreciated.
do the mapping for db column and class var name based on camelCase conversion basded on underscore _ separated name
you could try using
CREATE VIEW disbursement_payload AS (
SELECT iso_number AS currency
, trans_desc AS reason_type
, account_number AS receiver_rarty
, amount AS amount
FROM m_payment_detail
INNER JOIN m_loan_transaction
ON m_payment_detail.`id`= m_loan_transaction.`payment_detail_id`
AND m_payment_detail.`payment_type_id`=2
);
the view code is SQL code and hibernate see a view as a table, so the conversion of column name is base on the same rules
and a suggestion you should not use (older) implicit join based on where condition you should use (more recent) explici join sintax ..

MySQL to MSSQL keep foreign key relationships

I am currently trying to migrate from an old MySQL (5.0) to MSSQL. Because I must keep the primary key relationships, I am now facing a problem. Some data inside a table begin with the id of 6102 instead of one. I can solve this by increasing the seed, which works. Now, after several thousand of data sets, I have some leaps e.g. from id 22569 to 22597. This occurres multiple times.
What I basically do at the moment is, select all data from the source db (MySQL), map them into a generated model und try to map this model to my target model (MSSQL). (I do this because the target, new structure differs a little from the existing one.) When I ignore those leaps, I am getting later on several other tables a foreign key violation.
So my solution currently would be, to count from the beginning each mapping and when the id of the current model differs from the counter, to reset manually the seed in the database.
DBCC CHECKIDENT (mytable, RESEED, idFromCurrentModel);
Is there a possibility to force entity framework, respectively SQL Server to accept the id from my model instead of ignoring it and use the ident value?
Thanks for reading and best regards
EDIT
Just if anybody is wondering how I solved this, here it is:
var context = new TestEntities();
// map mysql data to mssql model and convert data
// let's assume I did this
var mapped = new List<Test>()
{
new Test() {id= 42, bar = "foo", created = DateTime.Now},
new Test() {id= 1337, bar = "bar", created = DateTime.Now}
};
var transaction = context.Database.BeginTransaction();
context.Database.ExecuteSqlCommand("SET IDENTITY_INSERT [SeedingTest].[dbo].[Test] ON");
context.Test.AddRange(mapped);
context.SaveChanges();
context.Database.ExecuteSqlCommand("SET IDENTITY_INSERT [SeedingTest].[dbo].[Test] OFF");
transaction.Commit();
context.Dispose();
This only works when I do this:
Right click on my *.edmx file, open, and remove the
StoreGeneratedPattern="Identity"
in your identity column. In my case this looked like this:
...
<Property Name="id" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
...
After removing this, EF was no longer ignoring my set id's.
Source
Additional information:
Adding this attribute
[DatabaseGenerated(DatabaseGeneratedOption.None)]
to my id in my generated model, did not work.
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int foo { get; set; }
public string bar { get; set; }
...
The easiest way is to set the seed initially to the current max Id value + 1. Then, when inserting the converted rows do the following
set identity_insert on tablename -- stops generation of IDENTITY, requires user to supply it
insert into tablename values (Id....) -- supply value of Id
set identity_insert_off tablename -- turn inedtity generation back on
This does it quite nicely.

Getting identity column value using entity framework 4.1

I'm using entity framework 4.1 (VS 2010, SQL Server 2012) for inserting data into a database.
First I create an instance of an object, fill the properties with values and call AddObject(), like this:
VideoData videodata = new VideoData();
videodata.StartCaptureTime = startCaptureTime;
videodata.EndCaptureTime = endCaptureTime;
videodata.CameraID = CameraID;
using (var context = new PercEntities())
{
if (context.VideoDatas.Where(c => c.VideoID == videoID).Count() == 0)
{
var videoData = new VideoData
{
StartCaptureTime = startCaptureTime,
EndCaptureTime = endCaptureTime,
CameraID = CameraID,
};
context.VideoDatas.AddObject(videoData);
context.SaveChanges();
}
}
The thing is, that the table in the database has an identity column:
VideoID int IDENTITY(1,1)
and I need to get the value inserted by the identity function in order to fill additional objects, that have the VideoID as a foreign key. for example:
FrameData frameData = new FrameData();
frameData.VideoID = videodata.VideoID;
frameData.Path = path;
The only thing I could think of was to query for the max identity right after AddObject(videoData), but I'm afraid of race conditions.
I'm new to Entity Framework, so I'd be happy for any guidance on this.
If you have other objects which require VideoID as FK you just need to correctly configure your navigation properties between VideoData and those other types and EF will handle it for you.
Call to AddObject does not insert your data to database and because of that you cannot get the identity value after this call. Only call to SaveChanges will push all your changes to database and during this call EF will handle referential integrity internally (but only if you have your model correctly configured with relations).
After calling SaveChanges your VideoID should be populated automatically if you have everything correctly configured.

Select column from non-generic DbSet?

I want to implement a function that accepts a DbSet (non-generic), a string, and object, and returns DbSet. something like the following pseudu:
public static DbSet Any(DbSet set, string propertyName, objectParameter)
{
var tableName = set.TableName;
var columnName = set.GetColumnNameForProperty(propertyName);
var query = string.Format("SELECT TOP(1) {0} FROM {1} WHERE {0} = {2}",
columnName,
tableName,
objectParameter);
}
I think that SQL query is enough since I'll be able to execute it directly on the Database (context.Database.ExecuteSql).
What I want to do is get the table name from the given DbSet, then the column name in the database.
It is not possible from non generic DbSet but this problem can be easily solved by using:
public static IEnumerable<T> Any(DbSet<T> set, string property, objectParameter)
where T : class
{ ... }
Returning DbSet doesn't make sense because once you query data it is not DbSet anymore.
The bigger problem is getting table name from generic DbSet / ObjectSet because this information is not available from those classes. It is almost impossible to get it at all because it requires accessing non public members of items from MetadataWorkspace.

LINQ + type tables best practices

Whats the best design pattern to use for LINQ and type tables that exist in SQL.
I have tables in SQL that constrain values to type values, and I want to be able to use this in my C# code as strongly typed values.
My current approach for a 'PackageStatus' type is as follows:
SQL Table
PackageStatusType (int)
desc (varchar)
C# Class - using LINQ
public class PackageStatusType
{
static PackageStatusType()
{
var lookup = (from p in DataProvider.ShipperDB.PackageStatus
select p).ToDictionary(p => p.Desc);
Unknown = lookup["Unknown"];
LabelGenerated = lookup["Label generated"];
ReadyForCollection = lookup["Ready for pickup"];
PickedUp = lookup["Picked up"];
InTransit = lookup["In Transit"];
DeliveryAttempted = lookup["Delivery attempted"];
DeliveredByHand = lookup["By hand"];
DeliveryFailed = lookup["Delivery failed"];
Delivered = lookup["Delivered"];
Voided = lookup["Voided"];
}
public static ShipperDB.Model.PackageStatus Unknown;
public static ShipperDB.Model.PackageStatus LabelGenerated;
public static ShipperDB.Model.PackageStatus ReadyForCollection;
public static ShipperDB.Model.PackageStatus PickedUp;
public static ShipperDB.Model.PackageStatus InTransit;
public static ShipperDB.Model.PackageStatus DeliveryAttempted;
public static ShipperDB.Model.PackageStatus DeliveryFailed;
public static ShipperDB.Model.PackageStatus Delivered;
public static ShipperDB.Model.PackageStatus DeliveredByHand;
public static ShipperDB.Model.PackageStatus Voided;
}
I then can put PackageStatusType.Delivered in my C# code and it will correctly reference the right LINQ entity.
This works fine, but makes me wonder:
a) how can i make this more efficient
b) why doesn't Microsoft seem to provide anything to create strongly typed type tables
c) is my database design even a good one?
d) what is everyone else doing!
thanks!
Linq to SQL allows you to map a string or int column in a database to an enumeration in your C# code. This allows you to let Linq to SQL to map these values for you when you select from the database. In this case, I would change my package status column to be either an int column with the values from the enumeration or a string that represents the values from the enumeration.
In your case, I would have a PackageStatus enumeration with the different values that you specified, and then using the ORM designer or SQLMetal, map that column to that enumeration. The only caveat is that the string values in the column in the database must match the values in the enumeration as Linq to SQL will use Enum.Parse() to map the string values from the database to the enumeration or make sure that the int values in the database match the values from the enumeration.
This is more efficient as you don't even need to map the lookup table at all in the code.
http://msdn.microsoft.com/en-us/library/bb386947.aspx#EnumMapping describes how this works.