Magic Casting to collection of results - simple.data

In the Simple.Data examples, there is an example of 'Magic Casting':
// When you assign the dynamic record to a static type, any matching properties are auto-mapped.
var db = Database.Open();
Customer customer = db.Customers.FindByCustomerId(1);
Does Simple.Data also magically cast if there are multiple records returned? Something like this:
var db = Database.Open();
IEnumerable<Customer> customers = db.Customers.FindBySurname("Smith");
Obviously I have tried the above and it doesn't work ("Cannot implicitly convert type" from SimpleQuery to my concrete type). Any advice would be welcome.

FindBySurname returns a single record. If you use FindAllBySurname you'll get an enumerable, which should magic cast OK. (If for some reason it doesn't, you can call .Cast() on it.)

Related

Symbol was not found when using tmpaccountsum variable in form

In the ReqTransPO form I want to use the tmpAccountSum table to store some values in which I later need to filter my grid.
In the classdeclaration I declared:
tmpAccountSum mytable;
In a helper method I have:
//Store data in tmptable
ttsbegin;
mytable.AccountNum = _reqTrans.RefId;
mytable.Txt = _reqPo.RefId;
mytable.Voucher = enum2str(_prodstatus);
mytable.insert();
ttscommit;
I don't get an error on 'mytable' but can't really use it / it's not initialized. If I add a watch in debug I see:
Error: Symbol "mytable" was not found
If I declare mytable locally it works ok.
Guess I'm doing something wrong?
Thanks in advance,
Mike
My extrasensory perception tells me, that your helper method is static.
Static methods do not have access to instance variables declared in classDeclaration.

Logical Thinking: Using Dynamic vs Static Values to Represent Data

I don't think I am asking the question correctly, but hopefully you know what I am asking.
What are pros and cons of using a string value to represent a database field (or any variable) vs using an enumeration or constant? I am not asking about the datatype, but hows its handled on the back-end. I'll use LINQ to SQL for an example.
My thinking is that by using an enumerable or constant it's: easier to read, ensures compatibly should the values ever need to be changed, and the value is hard coded -so to speak- so there are less chances of an error caused by a typo. On the flip side, do I really need a class/structure with member enumerations that essentially act as a look up for the value I want?
Using an Constant
Module Trip
Public Const OPEN As String = "Open"
Public Const PENDING_PAYMENT As String = "Pending Payment"
Public Const CANCELLED As String = "Cancelled"
Public Const CLOSED As String = "Closed"
End Module
Dim product = From p In db.Payments
Where p.PaymentId = PaymentId
For Each item In product
item.Status = PayStatus.PENDING_PAYMENT
Next
Using a string
Dim product = From p In db.Payments
Where p.PaymentId = PaymentId
For Each item In product
item.Status = "Pending Payment"
Next
As one of the comments says, the common way to deal with this is using a lookup table in the database. In its most simple form, you would have a class, let's say PaymentStatus:
Class PaymentStatus
Public Property Id As Integer
Public Property Name As String
End Class
and Payment would have reference property like
Public Property PaymentStatus As PaymentStatus
This way, you can always get the options from the database and you will never make a typo in code. It's also much easier to add options or to change descriptions.
For instance, think of what you need to do if you'd decide that "Cancelled" needs to be differentiated into "Cancelled by user" (the old status) and "Cancelled by system" (a new status introduced by new business logic). You'd need a script to update all records in the database to the new string (and change the code, but you'd be changing code anyway). A lookup table allows you to update only one record (and add a new one in this example).

LINQ and web service cannot return anonymous types, and you cannot construct an object in a query?

Web services cannot return an anonymous type.
If you are building a LINQ query using classes through a datacontext... you cannot construct instances of those classes in a query.
Why would I want to do this? Say I want to join three "tables" or sets of objects. I have three items with a foreign key to each other. And say the lowest, most detailed of these was represented by a class that had fields from the other two to represent the data from those. In my LINQ query I would want to return a list of the lowest, most detailed class. This is one way I have decided to "join some tables together" and return data from each of them via LINQ to SQL via a WebService. This may be bad practice. I certainly do not like adding the additional properties to the lowest level class.
Consider something like this... (please ignore the naming conventions, they are driven by internal consideration) also for some reason I need to instantiate an anonymous type for the join... I don't know why that is... if I do not do it this way I get an error...
from su in _dataContext.GetTable<StateUpdate>()
join sfs in _dataContext.GetTable<SystemFacetState>()
on new { su.lngSystemFacetState } equals new { lngSystemFacetState = sfs.lngSystemFacetState }
join sf in _dataContext.GetTable<SystemFacet>()
on new { sfs.lngSystemFacet } equals new { lngSystemFacet = sf.lngSystemFacet }
join s in _dataContext.GetTable<System>()
on new { sf.lngSystem } equals new {lngSystem = s.lngSystem}
select new
{
lngStateUpdate = su.lngStateUpdate,
strSystemFacet = sf.strSystemFacet,
strSystemFacetState = sfs.strSystemFacetState,
dtmStateUpdate = su.dtmStateUpdate,
dtmEndTime = su.dtmEndTime,
lngDuration = su.lngDuration,
strSystem = s.strSystem
}
).ToList();
Notice I have to build the anonymous type which is composed of pieces of each type. Then I have to do something like this... (convert it to a known type for transport via the web service)
result = new List<StateUpdate>(from a in qr select(new StateUpdate
{
lngStateUpdate = a.lngStateUpdate,
strSystemFacet = a.strSystemFacet,
strSystemFacetState = a.strSystemFacetState,
dtmStateUpdate = a.dtmStateUpdate,
dtmEndTime = a.dtmEndTime,
lngDuration = a.lngDuration,
strSystem = a.strSystem
}));
It is just awful. And perhaps I have created an awful mess. If I am way way off track here please guide me to the light. I feel I am missing something fundamental here when I am adding all these "unmapped" properties to the StateUpdate class.
I hope someone can see what I am doing here so I can get a better way to do it.
You can create a 'dto' class which just contains the properties you need to return and populate it instead of the anonymous object:
public class Result
{
public string lngStateUpdate
{
get;
set;
}
... // other properties
}
then use it like this:
from su in _dataContext.GetTable<StateUpdate>()
...
select new Result
{
lngStateUpdate = su.lngStateUpdate,
... // other properties
}
Nitpick note - please ditch the Hungarian notation and camel casing for properties :)
I think the answer is to create another object to serve as a DTO. This object would not be mapped to the data context and can contain fields that cross the mapped objects. This solves the problems of repetitive properties in the mapped objects, and allows for instantiation of the DTO class in the query as it is not mapped.
FYI: with respect to the problem with the join- I revisited that and I think I may have had the inner and outer components of the join switched around before.

How to convert linq entitySet AND CHILDREN to lists?

I ran into an error when trying to serialize a linq entitySet. To get around this i converted the entitySet to a list. The problem I have run into now is that it's child entity sets are not converting to a list and when I try to serialize the parent those are now throwing an error. Does anyone know of a way to convert a linq entitySet AND it's children to lists?
p.s. I'm new to linq so if any of this dosn't make sense let me know
Just project onto new types:
var q = from e in Entities
select new
{
Id = e.Id,
Name = e.Name,
Children = from c in e.Children
select new
{
Id = c.Id,
Name = c.Name,
// etc.
},
// etc.
};
var s = serializer.Serialize(q);
I am guessing you are trying to serialize to XML.
Either way, the problem stems from the circular references in LINQ entity objects. Lets say you have a main table Customers with a second table Orders. The Customers entity has a reference to all of the Orders this customer has (typically Customer.Orders). The Orders entity has a reference to the customer entity (typically Order.Customer). When the serializer tries to serialize this object, it recognizes the circular reference and throws an error.
In order to do what you want, you have to write your own serializer or convert the objects to something that can be directly serialized, like custom serialization objects which contain just the information you want to show up in the serialized version.

Populate ParameterCollection w/ sp_columns (or INFORMATION_SCHEMA.Columns) Results

I'd like to build a ParameterCollection object based on the results of either execute sp_columns MyTableName or SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = 'MyTableName'.
The problem I'm having is assigning the appropriate data type to each Parameter ... I'm unsure of how to gather that information from either of the above two queries and convert it into a System.Data.DbType or System.TypeCode.
Any help is greatly appreciated.
Links: MSDN: sp_columns, MSDN: Information Schema.Columns
Edit: I guess what I'm looking for is functionality similar to Type.GetType("TypeName") that would accept a SQL data type. For example, DbType.GetType("int") or DbType.GetType("varchar").
Edit: Links from Answer: MSDN: Enum.Parse Method
It's actually really easy to do :-) SqlDbType is an enum, and there's a nice static function on the Enum class which accomplishes just what your looking for:
private SqlDbType ConvertType(string typeName)
{
return (SqlDbType)Enum.Parse(typeof(SqlDbType), typeName, true);
}
With this, you should have no trouble converting the output from your INFORMATION_SCHEMA query into a collection of SqlParameters.

Resources