代码之家  ›  专栏  ›  技术社区  ›  TToni

如何使用Linq2Sql将多个数据库列存储到一个数组中

  •  1
  • TToni  · 技术社区  · 15 年前

    我必须处理多个SQL Server表,这些表通常如下所示:

    int id_this, int id_that, ..., double Value1, double Value2, ..., double Value96
    

    public class Foo
    {
        public int Id_This { get; set; }
        public int Id_That { get; set; }
        ...
        public double Value[];
    }
    

    值数组当然是一个属性,但我想你明白了。

    问题是,如何尽可能轻松地将96列放入数组中。

    我可以用一个普通的SqlDataReader实现这一点,因为DataRow允许索引访问,但我想知道我是否可以声明一些属性或编写一些最低数量的代码来直接将该类与LINQ2SQL一起使用。

    至少,我想这样做

    dataContext.ExecuteQuery<Foo>("SELECT * FROM Foo");
    
    1 回复  |  直到 15 年前
        1
  •  2
  •   Marc Gravell    15 年前

    哦,那是。。。美好的这个 DataContext ExecuteReader ,这是一种痛苦(但可以理解,因为它想表现为ORM)。老实说,我很想使用ADO.NET来处理这个表,但是如果您已经将宽表映射到 您应该能够使用常规C#或反射。

    Foo foo = new Foo { Id_This = obj.Id_This, Id_That = obj.Id_That,
        Values = new double[] {obj.Value1, obj.Value2, ... } };
    

    如果您有多个表。。。反射,可能通过 Expression :

    using System;
    using System.Collections.Generic;
    using System.Linq.Expressions;
    class FooUgly
    {
        public int IdThis { get; set; }
        public int IdThat { get; set; }
        public double Value1 { get; set; }
        public double Value2 { get; set; }
        public double Value3 { get; set; }
    }
    class Foo
    {
        public int IdThis { get; set; }
        public int IdThat { get; set; }
        public double[] Values { get; set; }
        public Foo() { }
        internal Foo(FooUgly ugly)
        {
            IdThis = ugly.IdThis;
            IdThat = ugly.IdThat;
            Values = extractor(ugly);
        }
        // re-use this!!!
        static readonly Func<FooUgly, double[]> extractor =
            ValueExtractor<FooUgly, double>.Create("Value", 1, 3);
    }
    static class Program
    {
        static void Main()
        {
            FooUgly ugly = new FooUgly { IdThis = 1, IdThat = 2, Value1 = 3, Value2 = 4, Value3 = 5 };
            Foo foo = new Foo(ugly);
        }
    }
    static class ValueExtractor<TFrom,TValue>
    {
        public static Func<TFrom, TValue[]> Create(string memberPrefix, int start, int end)
        {
            if(end < start) throw new ArgumentOutOfRangeException();
            ParameterExpression param = Expression.Parameter(typeof(TFrom), "source");
            List<Expression> vals = new List<Expression>();
            for(int i = start ; i <= end ; i++) {
                vals.Add(Expression.PropertyOrField(param, memberPrefix + i));
            }
            Expression arr = Expression.NewArrayInit(typeof(TValue), vals);
            return Expression.Lambda<Func<TFrom, TValue[]>>(arr, param).Compile();
        }
    }