Как я могу добавить свои атрибуты к Сгенерированным Кодом свойствам классов Linq2Sql?

В качестве вариации решения yasimturks я определил одну функцию и несколько значений enum вместо пяти макросов.

Использование:

if (systemVersion(LessThan, @"5.0")) ...

.h файл:

typedef enum {
  LessThan,
  LessOrEqual,
  Equal,
  GreaterOrEqual,
  GreaterThan,
  NotEqual
} Comparison;

BOOL systemVersion(Comparison test, NSString* version);

.m файл:

BOOL systemVersion(Comparison test, NSString* version) {
  NSComparisonResult result = [[[UIDevice currentDevice] systemVersion] compare: version options: NSNumericSearch];
  switch (test) {
    case LessThan:       return result == NSOrderedAscending;
    case LessOrEqual:    return result != NSOrderedDescending;
    case Equal:          return result == NSOrderedSame;
    case GreaterOrEqual: return result != NSOrderedAscending;
    case GreaterThan:    return result == NSOrderedDescending;
    case NotEqual:       return result != NSOrderedSame;
  }
}

Вы должны добавить префикс вашего приложения к именам, особенно к типу Comparison.

22
задан ArielBH 26 December 2008 в 11:10
поделиться

6 ответов

Согласно просьбе вот подход с помощью CustomTypeDescriptor для редактирования атрибутов во времени выполнения; примером здесь являются формы победы, но должно быть довольно просто подкачать его в 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<Foo> {
                            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<PropertyDescriptor> list = new List<PropertyDescriptor>(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; } }
}
5
ответ дан Marc Gravell 29 November 2019 в 04:20
поделиться

Можно использовать в своих интересах новую функциональность Метаданных в Системе. ComponentModel. DataAnnotations, который позволит нам разделять 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; }
}
39
ответ дан Jason Wicker 29 November 2019 в 04:20
поделиться

Можно хотеть рассмотреть использование шаблоны T4 охраны Damien для Linq К Sql. Изменение его шаблонов, скорее всего, дало бы Вам результаты, которые Вы ищете.

Hope это помогает!

1
ответ дан Brad Leach 29 November 2019 в 04:20
поделиться

Это - типичная проблема с генерацией кода; в то время как можно добавить участников и атрибуты уровня класса через дополнительный частичный класс, Вы не можете добавить атрибуты к сгенерированным участникам. Для компенсации некоторые основанные на атрибуте механизмы позволяют Вам определять атрибуты в классе (называющий участника), но не любой из тех Вы цитируете.

Одна жесткая опция состояла бы в том, чтобы записать TypeDescriptionProvider, который предоставляет пользовательский PropertyDescriptor определения для свойств. Это позволило бы Вам полностью управлять метаданными, используемыми UI обязательные инструменты как PropertyGrid, DataGridView, и т.д.

Однако это - возможно слишком много работы просто для установки некоторых UI propertiex, если можно также установить их вручную! Но если Вы интересуетесь преследованием той опции, сообщите мне - это - знакомая область мне, но слишком много кода для записи примера, если Вы не хотите его.

Примечание: если Вы используете PropertyGrid, то Вы не можете устанавливать свойства вручную, но можно записать TypeConverter, который является немного меньшим количеством работы, чем полное TypeDescriptionProvider; просто наследуйтесь от ExpandableObjectConverter и переопределите GetProperties(). Вам все еще будет нужен контейнер PropertyDescriptor, так все еще не тривиальный...

1
ответ дан Marc Gravell 29 November 2019 в 04:20
поделиться

Можно использовать частичный класс, чтобы заставить объект реализовать интерфейс, который объявляет те же свойства объекта и затем помещает атрибуты на интерфейс.

Этот путь можно использовать интерфейсный тип для получения атрибутов от свойств.

я не знаю, будете ли Вы в состоянии использовать атрибуты этот путь, но можно попробовать что-то как этот.

Пример:


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
{
//...
}
1
ответ дан Rafael Romão 29 November 2019 в 04:20
поделиться

Можно также писать/использовать другой генератор кода вместо MSLinqToSQLGenerator по умолчанию.

Одна опция начать с этот .

я создал свое собственное, согласно моим потребностям. Я не знаю, существует ли способ указать, какие атрибуты должны быть помещены в каждое свойство с помощью Разработчика DBML или xml файла, но возможно можно найти способ использовать эту альтернативу для помощи Вам с Вашей проблемой.

1
ответ дан Rafael Romão 29 November 2019 в 04:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: