Вам нужно объявить функцию, определенную пользователем WITH SCHEMABINDING
, чтобы успокоить «детерминированное» требование индекса в вычисленном столбце.
Функция, объявленная WITH SCHEMABINDING
, сохранит дополнительные знания об объектных зависимостях (например, столбцы в таблице) и предотвратит любые изменения этих столбцов, если только сама функция не будет удалена заранее.
Детерминированные функции также могут помочь Sql Server в оптимизации его планов выполнения, большинство особенно проблема защиты Хэллоуина .
Вот пример создания индекса в вычисленном столбце с использованием связанной с схемой функции:
create function [dbo].[FullNameLastFirst]
(
@IsPerson bit,
@LastName nvarchar(100),
@FirstName nvarchar(100)
)
returns nvarchar(201)
with schemabinding
as
begin
declare @Result nvarchar(201)
set @Result = (case when @IsPerson = 0 then @LastName
else case when @FirstName = '' then @LastName
else (@LastName + ' ' + @FirstName) end end)
return @Result
end
create table Person
(
isperson bit,
lastname nvarchar(100),
firstname nvarchar(100),
fullname as [dbo].[FullNameLastFirst] (isperson, lastname, firstname)
)
go
insert into person(isperson, lastname, firstname) values (1,'Firstname', 'Surname')
go
create index ix1_person on person(fullname)
go
select fullname from Person with (index=ix1_person) where fullname = 'Firstname Surname'
go
Нет быстрого способа получить атрибуты. Но код должен выглядеть так (кредит на Aaroonate ):
var t = typeof(YourClass);
var pi = t.GetProperty("Id");
var hasIsIdentity = Attribute.IsDefined(pi, typeof(IsIdentity));
Если вам нужно получить свойства атрибута, то
var t = typeof(YourClass);
var pi = t.GetProperty("Id");
var attr = (IsIdentity[])pi.GetCustomAttributes(typeof(IsIdentity), false);
if (attr.Length > 0) {
// Use attr[0], you'll need foreach on attr if MultiUse is true
}
Если вы используете .NET 3.5, вы можете попробовать с деревьями выражения. Это безопаснее, чем отражение:
class CustomAttribute : Attribute { }
class Program
{
[Custom]
public int Id { get; set; }
static void Main()
{
Expression<Func<Program, int>> expression = p => p.Id;
var memberExpression = (MemberExpression)expression.Body;
bool hasCustomAttribute = memberExpression
.Member
.GetCustomAttributes(typeof(CustomAttribute), false).Length > 0;
}
}
Вы можете использовать общий (общий) метод для чтения атрибута над заданным MemberInfo
public static bool TryGetAttribute<T>(MemberInfo memberInfo, out T customAttribute) where T: Attribute {
var attributes = memberInfo.GetCustomAttributes(typeof(T), false).FirstOrDefault();
if (attributes == null) {
customAttribute = null;
return false;
}
customAttribute = (T)attributes;
return true;
}