如何在Linq2SQL实体上自定义属性?

时间:2021-08-08 16:48:37

I know you can customise entities through partial classes, but what is the general approach for modifying properties on entities? What if i want to change the logic in the get/set? What about adding attributes? I don't want to edit the auto generated code - how do people get around this?

我知道你可以通过部分类来定制实体,但是修改实体属性的一般方法是什么?如果我想更改get / set中的逻辑怎么办?添加属性怎么样?我不想编辑自动生成的代码 - 人们如何解决这个问题?

5 个解决方案

#1


Don't autogenerate code at all. You can build your own linq to sql classes without using the designer.

根本不要自动生成代码。您可以在不使用设计器的情况下构建自己的linq到sql类。

Edit: My lazy way of doing this would be to autogenerate the code, copy paste it into the non generated file, and delete the designer files. Up to you though.

编辑:我这样做的懒惰方式是自动生成代码,将其粘贴到非生成的文件中,然后删除设计器文件。尽管如此。

#2


The Linq2SQL classes are partial classes, which means you can easily extend them by adding your own separate file and declaring another part of the partial class in there.

Linq2SQL类是部分类,这意味着您可以通过添加自己的单独文件并在其中声明部分类的另一部分来轻松扩展它们。

In that file, you can customize the class as needed - and since it's a separate file, the code generation will not overwrite it.

在该文件中,您可以根据需要自定义类 - 由于它是一个单独的文件,因此代码生成不会覆盖它。

If you look at e.g. the "Contact" class in the AdventureWorks database, Linq2SQL will generate this in your AdventureWorks.designer.cs file:

如果你看一下,例如在AdventureWorks数据库中的“Contact”类,Linq2SQL将在您的AdventureWorks.designer.cs文件中生成它:

[Table(Name="Person.Contact")]
public partial class Contact : INotifyPropertyChanging, INotifyPropertyChanged
{

Now you can add a "Contact.cs" file to your project, and extend that partial class, e.g. by introducing a new property "DisplayName":

现在,您可以将“Contact.cs”文件添加到项目中,并扩展该部分类,例如通过引入新属性“DisplayName”:

public partial class Contact 
{
       public string DisplayName
       {  
          get { return string.Format("{0} {1}", FirstName, LastName); }
       }
    }

At compile time, these two parts of the class are merged together.

在编译时,类的这两部分合并在一起。

The other part are the partial methods - methods that are available for you to implement, but if they're not implemented, calls to them are being optimized out by the compiler.

另一部分是部分方法 - 可供您实现的方法,但如果它们未实现,则编译器会优化对它们的调用。

For each object class in Linq2SQL, a whole slew of partial methods (a new feature in .NET 3.0) are being created - up to you to implement those!

对于Linq2SQL中的每个对象类,都会创建一大堆部分方法(.NET 3.0中的新功能) - 由您来实现!

partial void InsertContact(Contact instance);
partial void UpdateContact(Contact instance);
partial void DeleteContact(Contact instance);

partial void OnLoaded();
partial void OnValidate(System.Data.Linq.ChangeAction action);
partial void OnCreated();

partial void OnFirstNameChanging(string value);
partial void OnFirstNameChanged();

partial void OnLastNameChanging(string value);
partial void OnLastNameChanged();

Plenty of extension points!

很多扩展点!

Marc

#3


As Linq2Sql Entities are not sealed you could derive from a Linq2Sql class and do your changes in the derived class.

由于Linq2Sql实体未被密封,您可以从Linq2Sql类派生并在派生类中进行更改。

In my projects, I wouldn't do any changes to a Linq2Sql class. Instead I build my own set of POCO's which I can tailor to my needs. Then I use Linq2Sql only to fill / persist my POCO's using a repository pattern.

在我的项目中,我不会对Linq2Sql类进行任何更改。相反,我建立了自己的POCO套装,我可以根据自己的需要量身定制。然后我只使用Linq2Sql来填充/保存我的POCO使用存储库模式。

Rob Connery has a great webcast series on his blog called ASP.NET MVC Storefront. In one of the first webcasts he covers using Linq2Sql as a repository in conjunction with POCO's

Rob Connery在他的博客上有一个很棒的网络广播系列,名为ASP.NET MVC Storefront。在其中一个首次网络广播中,他使用Linq2Sql作为POCO的存储库

#4


Check this out:

看一下这个:

It's WAY better than sqlmetal (which is what the designer uses to generate your code)

它比sqlmetal更好(这是设计师用来生成代码的东西)

http://plinqo.com/default.aspx?AspxAutoDetectCookieSupport=1

Requires a Codesmith license though, but IMHO is very worth it.

虽然需要Codesmith许可证,但恕我直言是非常值得的。

#5


Modifying the logic in get/set of properties in a class that isn't marked virtual isn't possible without some serious hacks (look into mocking frameworks for examples of how to get around those limitations). That is the whole point of marking something virtual, making it expendable at the cost of a virtual call and a performance hit.

如果没有一些严重的攻击,修改未标记为虚拟的类中的属性的get / set中的逻辑是不可能的(查看模拟框架以获取如何绕过这些限制的示例)。这就是将某些东西标记为虚拟的重点,使其成为虚拟呼叫和性能损失的牺牲品。

The Metadatatype tag, however, will allow you to annotate an existing class with attributes that you can't modify:

但是,Metadatatype标记允许您使用无法修改的属性注释现有类:

Note: stolen from this related question

注意:从这个相关问题中被盗

[MetadataType (typeof (BookingMetadata))]
public partial class Booking
{
 // This is your custom partial class     
}

public class BookingMetadata
{
 [Required] [StringLength(15)]
 public object ClientName { get; set; }

 [Range(1, 20)]
 public object NumberOfGuests { get; set; }

 [Required] [DataType(DataType.Date)]
 public object ArrivalDate { get; set; }
}

#1


Don't autogenerate code at all. You can build your own linq to sql classes without using the designer.

根本不要自动生成代码。您可以在不使用设计器的情况下构建自己的linq到sql类。

Edit: My lazy way of doing this would be to autogenerate the code, copy paste it into the non generated file, and delete the designer files. Up to you though.

编辑:我这样做的懒惰方式是自动生成代码,将其粘贴到非生成的文件中,然后删除设计器文件。尽管如此。

#2


The Linq2SQL classes are partial classes, which means you can easily extend them by adding your own separate file and declaring another part of the partial class in there.

Linq2SQL类是部分类,这意味着您可以通过添加自己的单独文件并在其中声明部分类的另一部分来轻松扩展它们。

In that file, you can customize the class as needed - and since it's a separate file, the code generation will not overwrite it.

在该文件中,您可以根据需要自定义类 - 由于它是一个单独的文件,因此代码生成不会覆盖它。

If you look at e.g. the "Contact" class in the AdventureWorks database, Linq2SQL will generate this in your AdventureWorks.designer.cs file:

如果你看一下,例如在AdventureWorks数据库中的“Contact”类,Linq2SQL将在您的AdventureWorks.designer.cs文件中生成它:

[Table(Name="Person.Contact")]
public partial class Contact : INotifyPropertyChanging, INotifyPropertyChanged
{

Now you can add a "Contact.cs" file to your project, and extend that partial class, e.g. by introducing a new property "DisplayName":

现在,您可以将“Contact.cs”文件添加到项目中,并扩展该部分类,例如通过引入新属性“DisplayName”:

public partial class Contact 
{
       public string DisplayName
       {  
          get { return string.Format("{0} {1}", FirstName, LastName); }
       }
    }

At compile time, these two parts of the class are merged together.

在编译时,类的这两部分合并在一起。

The other part are the partial methods - methods that are available for you to implement, but if they're not implemented, calls to them are being optimized out by the compiler.

另一部分是部分方法 - 可供您实现的方法,但如果它们未实现,则编译器会优化对它们的调用。

For each object class in Linq2SQL, a whole slew of partial methods (a new feature in .NET 3.0) are being created - up to you to implement those!

对于Linq2SQL中的每个对象类,都会创建一大堆部分方法(.NET 3.0中的新功能) - 由您来实现!

partial void InsertContact(Contact instance);
partial void UpdateContact(Contact instance);
partial void DeleteContact(Contact instance);

partial void OnLoaded();
partial void OnValidate(System.Data.Linq.ChangeAction action);
partial void OnCreated();

partial void OnFirstNameChanging(string value);
partial void OnFirstNameChanged();

partial void OnLastNameChanging(string value);
partial void OnLastNameChanged();

Plenty of extension points!

很多扩展点!

Marc

#3


As Linq2Sql Entities are not sealed you could derive from a Linq2Sql class and do your changes in the derived class.

由于Linq2Sql实体未被密封,您可以从Linq2Sql类派生并在派生类中进行更改。

In my projects, I wouldn't do any changes to a Linq2Sql class. Instead I build my own set of POCO's which I can tailor to my needs. Then I use Linq2Sql only to fill / persist my POCO's using a repository pattern.

在我的项目中,我不会对Linq2Sql类进行任何更改。相反,我建立了自己的POCO套装,我可以根据自己的需要量身定制。然后我只使用Linq2Sql来填充/保存我的POCO使用存储库模式。

Rob Connery has a great webcast series on his blog called ASP.NET MVC Storefront. In one of the first webcasts he covers using Linq2Sql as a repository in conjunction with POCO's

Rob Connery在他的博客上有一个很棒的网络广播系列,名为ASP.NET MVC Storefront。在其中一个首次网络广播中,他使用Linq2Sql作为POCO的存储库

#4


Check this out:

看一下这个:

It's WAY better than sqlmetal (which is what the designer uses to generate your code)

它比sqlmetal更好(这是设计师用来生成代码的东西)

http://plinqo.com/default.aspx?AspxAutoDetectCookieSupport=1

Requires a Codesmith license though, but IMHO is very worth it.

虽然需要Codesmith许可证,但恕我直言是非常值得的。

#5


Modifying the logic in get/set of properties in a class that isn't marked virtual isn't possible without some serious hacks (look into mocking frameworks for examples of how to get around those limitations). That is the whole point of marking something virtual, making it expendable at the cost of a virtual call and a performance hit.

如果没有一些严重的攻击,修改未标记为虚拟的类中的属性的get / set中的逻辑是不可能的(查看模拟框架以获取如何绕过这些限制的示例)。这就是将某些东西标记为虚拟的重点,使其成为虚拟呼叫和性能损失的牺牲品。

The Metadatatype tag, however, will allow you to annotate an existing class with attributes that you can't modify:

但是,Metadatatype标记允许您使用无法修改的属性注释现有类:

Note: stolen from this related question

注意:从这个相关问题中被盗

[MetadataType (typeof (BookingMetadata))]
public partial class Booking
{
 // This is your custom partial class     
}

public class BookingMetadata
{
 [Required] [StringLength(15)]
 public object ClientName { get; set; }

 [Range(1, 20)]
 public object NumberOfGuests { get; set; }

 [Required] [DataType(DataType.Date)]
 public object ArrivalDate { get; set; }
}