如题 我自己手动创建了一个LINQ to SQL实体类 然后映射该类的属性到表中的列
但是每次都说 列名***无效 ,
//第二步创建一个类,并将其映射到数据库表 (这种类通常也被称为实体类) //只需要添加tableAttribute属性实现映射,Name对应映射的表的名称 [Table(Name = "product")] public class product { private int id; private string name; private int c_id; private decimal price; private int number; //将类的属性和表的列进行映射 //column表示当前属性的映射! 当前属性!是属性不是字段! [Column(Storage = "id", AutoSync = AutoSync.OnInsert, IsPrimaryKey = true,IsDbGenerated=true)]//id public int Id { get { return id; } set { id = value; } } [Column(Storage = "name", DbType = "nvarchar(20)")]//名称 public string Name { get { return name; } set { name = value; } } [Column(Storage = "price", DbType = "money")]//价格 public decimal Price { get { return price; } set { price = value; } } [Column(Storage = "number", DbType = "int")] public int Number { get { return number; } set { number = value; } } [Column(Storage = "c_id", DbType = "int")] public int C_id { get { return c_id; } set { c_id = value; } } }
对应数据库的设计如下
每次就提示我
“System.Data.SqlClient.SqlException”类型的未经处理的异常在 System.Data.dll 中发生
其他信息: 列名 'Name' 无效。
列名 'Price' 无效。
[Column(Storage = "name", DbType = "nvarchar(20)")]//名称 public string Name { get { return name; } set { name = value; } }
你属性是Name,映射也是Name,数据库字段是p_name,当然无效了。
Price我就不说了。
改成下面这样就行了。
[Column(Storage = "p_name", DbType = "nvarchar(20)")]//名称 public string Name { get { return name; } set { name = value; } }
我前面设置了私有字段的 名字就是 name 我看的视频教程里说是 数据库里的列名不用和外部属性名称一样,当然我也按照你的方式试了 把所有的 属性名改得和列名一样 但是还是一样的错误
@无线电静默: 从你提供的代码,我可以看出这儿肯定是错的,至于你其他地方还有没有错误,
没看到就不知道了。
比如,你可能修改后忘记编译了,比如....
@爱编程的大叔: 太感谢了, 其实我是第一次接触LINQ toSQL 我看的教学视频中 那个讲师说的是 将手动创建的类与表对应[table(name="表的名称")], 然后属性对应表中的列 教学视频里说 名字不用对应 他的视频里也确实是那样做的 但是我就是不行
要把代码改成这样
[Column(Storage = "p_name", DbType = "nvarchar(20)")]//名称 public string P_name { get { return p_name; } set { p_name = value; } }
我改成这样成功了
所以我就很疑惑了,这里对你之前给的代码实际上是 将私有字段改成跟数据库里的字段一致(这个我可以理解,毕竟要关联起来),属性名称可以不一样(调用属性的时候,实际是去操作的私有字段,这样也可以与数据库中的列关联起来),但是这样并不成功。 有些写得很简省的代码 直接[column] 后面就是属性 这种代买直接也能运行 这样它通过什么方式 将属性和数据库里的列对应起来 之前我们讨论的那种至少还保证了我私有字段的名称是一样的 可以去数据库比对
private string _name; [Column(Name="p_name", Storage = "_name", DbType = "nvarchar(20)")]//名称 public string name { get { return _name; } set { _name = value; } }
你仔细看看这段声明吧。
Name/Storage/Propertyname三者是不同的。
应该是Name:="p_name",这样你的属性名字就可以保持为name了。
Storage是另外的用途。
我也是看着代码才看出来的。刚刚开始的回答是本能的,没有经过实践考验的,哈哈。
@爱编程的大叔:
从我自己试验的结果来看 当初设置私有字段的时候 名字的确可以不和数据库表里的一样 但是在映射属性的时候 要这样写
[Column(Name = "p_name", Storage = "_name", DbType = "nvarchar(20)")]
public string kkkk
{
get { return _name; }
set { _name = value; }
}
这样设置了column name="XXX" 时 这样 对应属性 和 私有字段的命名就可以比较自由了。 如果没有column name="XXX" 那么私有字段 和 属性的命名都被限制了 私有字段必须和数据库中的字段一样, 对应属性的名称也必须使用重构对私有字段封装后的那个自带的名称才能保证将数据取出来 这一点我十分不能理解~
不过你对我的提示确实太重要了 能不能理解先不说 至少先实现了 而且我觉得正常情况下你写这个才是正常的思路 先用Name 限定这个属性对应表的哪一列 Storage是将表中数据取出来放到对应私有字段中去。只有先将属性和列对应起来才能正常理解 不然 我完全可以多写几个属性 属性的数据类型都和数据库中的一样 对应映射不用name指定是哪一列 这样的话岂不是会乱套