首页 > 解决方案 > SqlBulkTools 的动态使用

问题描述

我正在尝试制作一个通用sqlbulktools方法,以便它可以将任何模型作为输入。下面是主要方法:

public void InsertOrUpdateTableMatchOnString<T>(string tableName, List<T> models) where T : class, IModel
    {
        BulkOperations bulk = new BulkOperations();

        using (TransactionScope trans = new TransactionScope())
        {
            using (SqlConnection conn = new SqlConnection(MyConString))
            {
                bulk.Setup<T>()
                    .ForCollection(models)
                    .WithTable(tableName)
                    .AddAllColumns()
                    .BulkInsertOrUpdate()
                    .SetIdentityColumn(x => x.Id)
                    .MatchTargetOn(x => x.AgreementId)
                    .MatchTargetOn(x => x.GetMatchOn())
                    .Commit(conn);
            }

            trans.Complete();
        }
    }

以下是用作输入的模型示例:

public class Company : IModel
{
    public long? Id { get; set; }
    public string Name { get; set; }
    public string BaseCurrency { get; set; }
    public string Address1 { get; set; }
    public string PostalCode { get; set; }
    public string City { get; set; }
    public string Country { get; set; }
    public string TelephoneNumber { get; set; }
    public string Contact { get; set; }
    public string WebSite { get; set; }
    public string Email { get; set; }
    public string CINumber { get; set; }
    public DateTime SignUpDate { get; set; }
    public int AgreementId { get; set; }

    public PropertyInfo GetMatchOn()
    {
        return this.GetType().GetProperties().First(p => p.Name == "Name");
    }

    public Company SetProperties(CompanyData data, Customer customer)
    {
        Name = data.Name;
        BaseCurrency = data.BaseCurrencyHandle.Code;
        Address1 = data.Address1;
        PostalCode = data.PostalCode;
        City = data.City;
        Country = data.Country;
        TelephoneNumber = data.TelephoneNumber;
        Contact = data.Contact;
        WebSite = data.WebSite;
        Email = data.Email;
        CINumber = data.CINumber;
        SignUpDate = data.SignUpDate;
        AgreementId = customer.ecid;

        return this;
    }
}

这是模型实现的接口:

public interface IModel
{
    long? Id { get; set; }
    int AgreementId { get; set; }
    PropertyInfo GetMatchOn();
}

问题是我不能GetMatchOn().MatchTargetOn(x => x.GetMatchOn())方法调用中使用该方法 - 它只会采用类似的属性.MatchTargetOn(x => x.AgreementId),否则我会收到错误消息。但我需要它是一种方法,因为它不是从模型到模型的相同属性,我想要匹配。这有可能吗?

标签: c#sql-serversqlbulktools

解决方案


感谢您为我指明正确的方向 Jeroen Mostert。最终为我工作的是向模型添加一个方法 - 像这样的 fx:

public Expression<Func<Company, object>> GetMatchOn()
        {
            ParameterExpression parameter = Expression.Parameter(typeof(Company));
            MemberExpression property = Expression.Property(parameter, "Name");
            UnaryExpression convertedProperty = Expression.Convert(property, typeof(object));
            Expression<Func<Company, object>> lambda = Expression.Lambda<Func<Company, object>>(convertedProperty, parameter);

            return lambda;
        }

然后像这样从 main 方法调用它:

public void InsertOrUpdateTableMatchOnString<T>(string tableName, List<T> models) where T : class, IModel<T, object>
        {
            BulkOperations bulk = new BulkOperations();

            using (TransactionScope trans = new TransactionScope())
            {
                using (SqlConnection conn = new SqlConnection(MyConString))
                {
                    bulk.Setup<T>()
                        .ForCollection(models)
                        .WithTable(tableName)
                        .AddAllColumns()
                        .BulkInsertOrUpdate()
                        .SetIdentityColumn(x => x.Id)
                        .MatchTargetOn(x => x.AgreementId)
                        .MatchTargetOn(models.First().GetMatchOn())
                        .Commit(conn);
                }

                trans.Complete();
            }
        }

推荐阅读