Hi,
I have this fragment of code:
SmsDataClassesDataContext dc = new SmsDataClassesDataContext();
// Get the customer
Customer currentCustomer = dc.Customers.Single( c => c.Hash1 == forThisHash );
// Get from Name (LINQ to XML)
var q = from c in thisSmsPack.Descendants("from")
select c;
string from = q.First().Value;
foreach ( XElement element in thisSmsPack.Descendants("to") )
{
// Create the queue
SmsQueue sq = new SmsQueue();
sq.CustomerId = currentCustomer.CustomerId;
sq.MsgFrom = from;
sq.MsgTo = element.Attribute("name").Value;
sq.MsgPhone = element.Attribute("phone").Value;
sq.MsgBody = element.Attribute("msg").Value;
sq.Priority = currentCustomer.SendsSmsAtPriority;
sq.DontSendUntil = GetNextSendDate();
// sq.TimeCreated = System.DateTime.Now;
currentCustomer.SmsQueues.Add(sq);
}
dc.SubmitChanges();
I am creating new instances of "SmsQueues", populating the values and when the foreach loop is finished I submit the changes. Given the new lambda/linq/anonymous types that .NET 3.5 has, is there a more "modern" way to accomplish the above?
As a side question, maybe related, can I return an existing type composed of different columns in the select part of the linq expression?
Suppose you have three tables:
T1 == T1.Id, T1.Name
T2 == T2.Id, T2.Phone
T3 == T3.Name, T3.Phone, T3.SomethingElse
Can I perform a LINQ query that returns:
T1.Name, T2.Phone, SomethingElseNew
And let .NET know that that is of Type T3 (and it's a new instance of it)? That way when I SubmitChanges, new T3 instances are inserted in the DB?
I don't know if I make myself clear :S
-
I don't have a system available to test this, but I think this (or something very close) should work.
CustomerId = currentCustomer.CustomerId; var sqrange = from element in thisSmsPack.Descendants("to") ) select new SmsQueue { // Create the queue MsgFrom = from, MsgTo = element.Attribute("name").Value, MsgPhone = element.Attribute("phone").Value, MsgBody = element.Attribute("msg").Value, Priority = currentCustomer.SendsSmsAtPriority, DontSendUntil = GetNextSendDate() // TimeCreated = System.DateTime.Now }; currentCustomer.SmsQueues.AddRange(sqrange);EDIT: Fixed the numerous syntax errors (as delineated in the comments)
tvanfosson : You probably need to use AddRange() rather than Add().Martín Marconcini : The select new new SmsQueue is a typo? Did you mean: select new SmsQueue ? The semicolons after each item should be commas. Also the currentCustomer.SmsQueues.Add(sq) (or AddRange) cannot be used because "sq" doesn't exist, what should I add there? :(Martín Marconcini : I found it. I needed to use: currentCustomer.SmsQueues.Add(sqrange); (it was obvious but still…) ;) I used AddRange instead of Add and changed the ";" for Commas after each statement. Also you had two times "new" in the select. But it worked. Thanks!!!Martín Marconcini : There's another syntax error, after Descendants("to") ) That second parenthesis doesn't go there. ;) -
You could do something like this (syntax may be off slightly, no intellisense here):
var q = T1.Join(T2, t => t.Id, t2 => t2.Id) select new T3{Name=t.Name,Phone=t2.Phone,SomethingElseNew="Chickens"};Martín Marconcini : Thanks, that helped me figure out that i needed commas instead of semi-colons. Now if I had a T4 and T3 had a FK to this T4 (T3.t4id), can I do a T4.T3s.Add() ? How would I reference that newly created T3? q.?Robert MacLean : When FK are correctly setup on the DB side LINQ will cope with them without the need for joins and you will be able to call the methods of the related objects as described. q would be an IEnumerable, so you would access it as you would any other collection (foreach loop, calling .first() etc...)
0 comments:
Post a Comment