tags:

views:

87

answers:

2

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

+2  A: 

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)

James Curran
You probably need to use AddRange() rather than Add().
tvanfosson
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. ;)
Martín Marconcini
A: 

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"};
Robert MacLean
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.?
Martín Marconcini
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<T3>, so you would access it as you would any other collection (foreach loop, calling .first() etc...)
Robert MacLean