Создание условной связи в Linq2SQL - PullRequest
0 голосов
/ 14 сентября 2011

Я использую linq2sql против старой системы баз данных.В этой системе есть три таблицы: Счета-фактуры, Пользователи и RegistrationUsers.Таблица Invoices имеет поле UID, которое обычно ссылается на ключ UID в таблице Users.НО, у этого также есть битовое поле IsSignup, которое указывает, что поле UID должно ссылаться на ключ UID в таблице RegistrationUsers.

Меня не особо волнует связь с таблицей RegistrationUsers, но у нас есть проблема, когда очень легко забыть проверить значение IsSignup при использовании сущностей linq2sql.Я бы хотел, чтобы отношения Invoices-> Users в сущностях были обусловлены битовым полем IsSignup.

Я попробовал несколько подходов.Сначала я попытался настроить OnLoaded:

public partial class Invoice
{
    partial void OnLoaded()
    {
        if (IsSignup)
        {
            InvoiceUser = null;
        }
    }
}

Это не удается, потому что он пытается установить нулевое значение поля UID при сохранении счета-фактуры, что мы не можем сделать.с DataLoadOptions, но также не смог найти способ заставить это работать.

Я мог бы просто изменить метод получения свойства InvoiceUsers, но тогда он будет перезаписываться каждый раз, когда изменяется dbml.1013 * Мне просто не повезло?

1 Ответ

0 голосов
/ 14 сентября 2011

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

Я использую шаблоны LINQ to SQL для T4 для генерации кода. Я вошел в файл .tt для этого конкретного файла .dbml и нашел часть, которая генерирует свойства для отношений. Затем я взломал оператор if, который изменил свойство, если оно применяется к этим конкретным отношениям:

    <#=code.Format(association.MemberAttributes)#><#=association.Type.Name#> <#=association.Member#>
    {
        get {
            <#if(association.Name == "InvoiceUser_Invoice"){#>
                            //HACK IN THE .TT FILE TO ALWAYS INCLUDE THIS CONDITIONAL RELATIONSHIP
            if(IsSignup){return null;}
            <#}#>
            <#if (needsSerializationFlag && serialization) {#>
            if (serializing && !<#=association.Storage#>.HasLoadedOrAssignedValue) {
                return null;
            }
            <#}#>
            return <#=association.Storage#>.Entity;
        }

Это позволяет сгенерированному коду для этого конкретного свойства получить желаемый результат:

    [Association(Name=@"InvoiceUser_Invoice", Storage=@"_InvoiceUser", ThisKey=@"UID", OtherKey=@"UID", IsForeignKey=true)]
    public InvoiceUser InvoiceUser
    {
        get {
            //HACK IN THE .TT FILE TO ALWAYS INCLUDE THIS CONDITIONAL RELATIONSHIP
                            if(IsSignup){return null;}
                            return _InvoiceUser.Entity;
        }
        set {
            InvoiceUser previousValue = _InvoiceUser.Entity;
            if ((previousValue != value) || (!_InvoiceUser.HasLoadedOrAssignedValue)) {
                SendPropertyChanging();
                if (previousValue != null) {
                    _InvoiceUser.Entity = null;
                    previousValue.Invoices.Remove(this);
                }
                _InvoiceUser.Entity = value;
                if (value != null) {
                    value.Invoices.Add(this);
                    _UID = value.UID;
                }
                else {
                    _UID = default(int);
                }
                SendPropertyChanged("InvoiceUser");
            }
        }
    }

Так что все еще неприятный взлом, но он по крайней мере предотвращает изменения в файле .dbml от удаления необходимых условных отношений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...