如何将我的属性添加到代码生成的Linq2Sql类属性?
我想为Linq 2 Sql类属性添加属性。 例如,此列可以在用户界面中浏览,也可以在UI中自读,目前为止。
我考虑过使用模板,有谁知道如何使用它? 还是别的什么?
一般来说,您是否会使用代码生成的类来解决这个问题?
根据要求,这是一种使用CustomTypeDescriptor
在运行时编辑属性的方法; 这里的示例是win-forms,但将它交换到WPF以查看它是否有效应该非常简单…
using System; using System.Collections.Generic; using System.ComponentModel; using System.Windows.Forms; // example POCO class Foo { static Foo() { // initializes the custom provider (the attribute-based approach doesn't allow // access to the original provider) TypeDescriptionProvider basic = TypeDescriptor.GetProvider(typeof(Foo)); FooTypeDescriptionProvider custom = new FooTypeDescriptionProvider(basic); TypeDescriptor.AddProvider(custom, typeof(Foo)); } public string Name { get; set; } public DateTime DateOfBirth { get; set; } } // example form static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.Run( new Form { Controls = { new DataGridView { Dock = DockStyle.Fill, DataSource = new BindingList { new Foo { Name = "Fred", DateOfBirth = DateTime.Today.AddYears(-20) } } } } }); } } class FooTypeDescriptionProvider : TypeDescriptionProvider { ICustomTypeDescriptor descriptor; public FooTypeDescriptionProvider(TypeDescriptionProvider parent) : base(parent) { } public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance) { // swap regular descriptor for bespoke (Foo) descriptor if (descriptor == null) { ICustomTypeDescriptor desc = base.GetTypeDescriptor(typeof(Foo), null); descriptor = new FooTypeDescriptor(desc); } return descriptor; } } class FooTypeDescriptor : CustomTypeDescriptor { internal FooTypeDescriptor(ICustomTypeDescriptor parent) : base(parent) { } public override PropertyDescriptorCollection GetProperties() { // wrap the properties return Wrap(base.GetProperties()); } public override PropertyDescriptorCollection GetProperties(Attribute[] attributes) { // wrap the properties return Wrap(base.GetProperties(attributes)); } static PropertyDescriptorCollection Wrap(PropertyDescriptorCollection properties) { // here's where we have an opportunity to swap/add/remove properties // at runtime; we'll swap them for pass-thru properties with // edited atttibutes List list = new List (properties.Count); foreach (PropertyDescriptor prop in properties) { // add custom attributes here... string displayName = prop.DisplayName; if (string.IsNullOrEmpty(displayName)) displayName = prop.Name; list.Add(new ChainedPropertyDescriptor(prop, new DisplayNameAttribute("Foo:" + displayName))); } return new PropertyDescriptorCollection(list.ToArray(), true); } } class ChainedPropertyDescriptor : PropertyDescriptor { // this passes all requests through to the underlying (parent) // descriptor, but has custom attributes etc; // we could also override properties here... private readonly PropertyDescriptor parent; public ChainedPropertyDescriptor(PropertyDescriptor parent, params Attribute[] attributes) : base(parent, attributes) { this.parent = parent; } public override bool ShouldSerializeValue(object component) { return parent.ShouldSerializeValue(component); } public override void SetValue(object component, object value) { parent.SetValue(component, value); } public override object GetValue(object component) { return parent.GetValue(component); } public override void ResetValue(object component) { parent.ResetValue(component); } public override Type PropertyType {get { return parent.PropertyType; } } public override bool IsReadOnly { get { return parent.IsReadOnly; } } public override bool CanResetValue(object component) {return parent.CanResetValue(component);} public override Type ComponentType { get { return parent.ComponentType; } } public override void AddValueChanged(object component, EventHandler handler) {parent.AddValueChanged(component, handler); } public override void RemoveValueChanged(object component, EventHandler handler) { parent.RemoveValueChanged(component, handler); } public override bool SupportsChangeEvents { get { return parent.SupportsChangeEvents; } } }
您可以利用System.ComponentModel.DataAnnotations中的新元数据function,这将允许我们将MetaData与现有域模型分开。
例如:
[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; } }
你可能想考虑使用Damien Guard的T4模板来实现Linq To Sql 。 修改他的模板很可能会给你你想要的结果。
希望这可以帮助!
这是代码生成的常见问题; 虽然您可以通过其他分部类添加成员和类级别属性,但您无法向生成的成员添加属性。 为了补偿,一些基于属性的机制允许您指定类中的属性(命名成员),但不能指定您引用的任何属性。
一个硬核选项是编写一个TypeDescriptionProvider
,为属性提供自定义PropertyDescriptor
定义。 这将允许您完全控制UI绑定工具(如PropertyGrid
, DataGridView
等)使用的元数据。
但是,如果您也可以手动设置它们,那么设置一些UI属性可能太多了! 但是如果你对追求这个选项感兴趣,请告诉我 – 这对我来说是一个熟悉的领域,但如果你不想要它,那么编写一个例子的代码太多了。
注意:如果您正在使用PropertyGrid
,那么您不能手动设置属性,但您可以编写TypeConverter
,这比完整的TypeDescriptionProvider
少一点工作; 只是从ExpandableObjectConverter
inheritance并覆盖GetProperties()
。 你仍然需要一个垫片PropertyDescriptor
,所以仍然不是微不足道的……
您可以使用partial类来使您的实体实现一个接口,该接口声明实体的相同属性,然后将属性放在接口上。
这样,您可以使用接口类型从属性中获取属性。
我不知道你是否能够以这种方式使用这些属性,但你可以尝试这样的东西。
例:
public interface IConcept { long Code { get; set; } [Unique] string Name { get; set; } bool IsDefault { get; set; } } public partial class Concept : IConcept { } [Table(Name="dbo.Concepts")] public partial class Concept { //... }
您还可以编写/使用其他代码生成器来代替默认的MSLinqToSQLGenerator。
一个选择就是这个 。
根据我的需要,我建立了自己的。 我不知道是否有办法使用DBML Designer或xml文件指示必须在每个属性中放置哪些属性,但也许您可以找到一种方法来使用此替代方法来帮助您解决问题。
上述就是C#学习教程:如何将我的属性添加到代码生成的Linq2Sql类属性?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1014630.html