开发者

Query and Assignment in a Single Step

开发者 https://www.devze.com 2023-03-27 16:13 出处:网络
I have a class that has 3 properties: class Three { int ID { get; set ;} string Name { get; set; } double Value { get; set; }

I have a class that has 3 properties:

class Three
{
   int ID { get; set ;}
   string Name { get; set; }
   double Value { get; set; }
}

I then have a linq query that returns a Queryable<Three> but only ID and Name are defined within the table.

var three = from t in db.Threes
            select t;

three = { {ID=1, Name="A", Value=0},{ID=2, Name="B", Value=0},...}

So Value is not defined within the db.Threes table so it defaults to 0 as doubles do. I then iterate over each item in var three to set Value based upon another table:

for (int i = 0; i < three.Count(); i++)
{
   three[i].Value = (from v in db.Values
                     where v.ThreeID = i.ID
                     select v.Value).First();
}

return three;

The Queryable<Three> three now contains definitions for .Value:

three = { {ID=1, Name="A", Value=99},{ID=2, Name="B", Value=100},...}

The key thing that I'm trying to do is to still return a Queryab开发者_开发问答le<Three>, but to also set the Value property.

Is there a better way to do this instead of using a for loop?

I'd like to be able to extend this to any class with a Value property that is assigned from another table; suppose I have a class Four:

class Four
{
   int ID {get; set;}
   string Name {get; set;}
   DateTime Date {get; set;}
   double Value {get; set;}
}

The first query would populate with ID, Name and Date and I still want to be able to assign Value. I feel like there is a better way to do this with linq that I just can't come up with.

Edit: suppose I'm calling db.GetTable<T> and Three and Four are really generic arguments that implement a .Value interface. I can't explicitly instantiate a generic type because I would have to hard code the properties.


I think you are looking for join. You are assigning values from another table whose id is the same as the Three table.

You can build back a Three object like this:

var three = from t in db.Threes
            join v in db.Values on t.ID equals v.ThreeID
            select new Three{
                            ID = t.ID, 
                            Name = t.Name,
                            Value = v.Value 
                         };

What you were doing before by looping, that is a performance hit. What happens is that you called to the database to loop it, then for each loop, you make another call back to the database. If your tables are linked by those Ids, then using this code makes 1 single database call and no in memory looping.


What about a simple join, assuming you have some common key?

var things = from t in db.Threes
             join v in db.Values on t.SomeId equals v.SomeId
             select new Three { ID = t.ID, 
                                Name = t.Name,
                                Value = v.Value 
                              };
0

精彩评论

暂无评论...
验证码 换一张
取 消